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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/docutils.js +21 -6
  3. package/global.d.ts +1 -0
  4. package/iframe.html +15 -0
  5. package/index.html +2 -1
  6. package/index.js +295 -335
  7. package/package.json +16 -17
  8. package/src/{RvfExportMenu/RvfExportMenu.tsx → ExportMenu/ExportMenu.tsx} +12 -12
  9. package/src/ExportMenu/index.tsx +1 -0
  10. package/src/{RvfExportMenuButton/RvfExportMenuButton.tsx → ExportMenuButton/ExportMenuButton.tsx} +5 -5
  11. package/src/ExportMenuButton/index.tsx +1 -0
  12. package/src/FeatureDetails/FeatureDetails.tsx +57 -0
  13. package/src/FeatureDetails/index.ts +1 -0
  14. package/src/FeaturesInfosListener/FeaturesInfosListener.tsx +73 -0
  15. package/src/FeaturesInfosListener/index.tsx +1 -0
  16. package/src/GeolocationButton/GeolocationButton.tsx +0 -1
  17. package/src/LayerTree/LayerTree.tsx +58 -0
  18. package/src/LayerTree/TreeItem/TreeItem.tsx +151 -0
  19. package/src/LayerTree/TreeItem/index.tsx +1 -0
  20. package/src/LayerTree/index.tsx +1 -0
  21. package/src/LayerTree/layersTreeContext.ts +4 -0
  22. package/src/LayerTree/layersTreeReducer.ts +158 -0
  23. package/src/{RvfLayerTreeButton/RvfLayerTreeButton.tsx → LayerTreeButton/LayerTreeButton.tsx} +5 -5
  24. package/src/LayerTreeButton/index.tsx +1 -0
  25. package/src/{RvfTopics/RvfTopics.tsx → LayerTreeMenu/LayerTreeMenu.tsx} +17 -13
  26. package/src/LayerTreeMenu/index.tsx +1 -0
  27. package/src/LayoutState/LayoutState.tsx +277 -0
  28. package/src/LayoutState/index.tsx +1 -0
  29. package/src/LinesNetworkPlanDetails/LinesNetworkPlanDetails.tsx +292 -0
  30. package/src/LinesNetworkPlanDetails/index.tsx +1 -0
  31. package/src/{RvfLineNetworkPlanLayer/RvfLineNetworkPlanLayer.tsx → LinesNetworkPlanLayer/LinesNetworkPlanLayer.tsx} +7 -9
  32. package/src/LinesNetworkPlanLayer/index.tsx +1 -0
  33. package/src/MobilityMap/MobilityMap.tsx +274 -60
  34. package/src/MobilityMap/MobilityMapAttributes.ts +46 -50
  35. package/src/NotificationDetails/NotificationDetails.tsx +468 -0
  36. package/src/NotificationDetails/index.ts +1 -0
  37. package/src/{NotificationLayer/NotificationLayer.tsx → NotificationsLayer/NotificationsLayer.tsx} +9 -4
  38. package/src/NotificationsLayer/index.tsx +1 -0
  39. package/src/Overlay/Overlay.tsx +1 -6
  40. package/src/OverlayContent/OverlayContent.tsx +87 -0
  41. package/src/OverlayContent/index.ts +1 -0
  42. package/src/OverlayDetails/OverlayDetails.tsx +47 -0
  43. package/src/OverlayDetails/index.ts +1 -0
  44. package/src/OverlayDetailsFooter/OverlayDetailsFooter.tsx +51 -0
  45. package/src/OverlayDetailsFooter/index.tsx +1 -0
  46. package/src/OverlayDetailsHeader/OverlayDetailsHeader.tsx +35 -0
  47. package/src/OverlayDetailsHeader/index.ts +1 -0
  48. package/src/OverlayFooter/OverlayFooter.tsx +41 -0
  49. package/src/OverlayFooter/index.tsx +1 -0
  50. package/src/OverlayHeader/OverlayHeader.tsx +44 -0
  51. package/src/OverlayHeader/index.tsx +1 -0
  52. package/src/PermalinkInput/PermalinkInput.tsx +28 -0
  53. package/src/PermalinkInput/index.tsx +1 -0
  54. package/src/RouteSchedule/RouteSchedule.tsx +22 -18
  55. package/src/RvfFeatureDetails/RvfFeatureDetails.tsx +22 -50
  56. package/src/RvfFeatureDetails/RvfLineNetworkDetails/RvfLineNetworkDetails.tsx +108 -104
  57. package/src/RvfFeatureDetails/RvfNotificationDetails/RvfNotificationDetails.tsx +189 -154
  58. package/src/RvfFeatureDetails/RvfSharedMobilityDetail/RvfSharedMobilityDetails.tsx +12 -14
  59. package/src/RvfFeatureDetailsTitle/RvfFeatureDetailsTitle.tsx +5 -5
  60. package/src/RvfMainLinkButton/RvfMainLinkButton.tsx +65 -0
  61. package/src/RvfMainLinkButton/index.tsx +1 -0
  62. package/src/RvfMobilityMap/RvfMobilityMap.tsx +183 -395
  63. package/src/RvfOverlayContent/RvfOverlayContent.tsx +2 -2
  64. package/src/RvfPoisLayer/RvfPoisLayer.tsx +2 -2
  65. package/src/RvfSearch/RvfSearch.tsx +1 -1
  66. package/src/RvfSellingPointsLayer/RvfSellingPointsLayer.tsx +2 -2
  67. package/src/RvfSharedMobilityLayerGroup/RvfSharedMobilityLayerGroup.tsx +23 -23
  68. package/src/RvfTarifZonenLayer/RvfTarifZonenLayer.tsx +2 -2
  69. package/src/Search/Search.tsx +11 -2
  70. package/src/{RvfSearchButton/RvfSearchButton.tsx → SearchButton/SearchButton.tsx} +5 -5
  71. package/src/SearchButton/index.tsx +1 -0
  72. package/src/ShadowOverflow/ShadowOverflow.tsx +20 -0
  73. package/src/ShadowOverflow/index.tsx +1 -0
  74. package/src/{RvfShare/RvfPermalinkButton/RvfPermalinkButton.tsx → ShareMenu/PermalinkButton/PermalinkButton.tsx} +4 -4
  75. package/src/ShareMenu/PermalinkButton/index.tsx +1 -0
  76. package/src/{RvfShare/RvfShare.tsx → ShareMenu/ShareMenu.tsx} +9 -11
  77. package/src/ShareMenu/index.tsx +1 -0
  78. package/src/{RvfShareMenuButton/RvfShareMenuButton.tsx → ShareMenuButton/ShareMenuButton.tsx} +6 -6
  79. package/src/ShareMenuButton/index.tsx +1 -0
  80. package/src/SingleClickListener/SingleClickListener.tsx +55 -113
  81. package/src/SingleClickListener/index.tsx +1 -1
  82. package/src/Station/Station.tsx +10 -3
  83. package/src/StationsLayer/StationsLayer.tsx +0 -1
  84. package/src/StopsSearch/StopsSearch.tsx +3 -4
  85. package/src/StopsSearch/index.tsx +2 -1
  86. package/src/WindowMessageListener/WindowMessageListener.tsx +7 -1
  87. package/src/{RvfZoomButtons/RvfZoomButtons.tsx → ZoomButtons/ZoomButtons.tsx} +9 -12
  88. package/src/ZoomButtons/index.tsx +1 -0
  89. package/src/icons/Geolocation/airport-14-svgrepo-com.svg +41 -0
  90. package/src/ui/Button/Button.tsx +9 -2
  91. package/src/ui/Checkbox/Checkbox.tsx +32 -0
  92. package/src/ui/Checkbox/index.tsx +1 -0
  93. package/src/ui/IconButton/IconButton.tsx +24 -4
  94. package/src/ui/Input/Input.tsx +17 -0
  95. package/src/ui/Input/index.tsx +1 -0
  96. package/src/ui/InputCopy/InputCopy.tsx +86 -0
  97. package/src/ui/InputCopy/index.tsx +1 -0
  98. package/src/ui/Select/Select.tsx +24 -0
  99. package/src/ui/Select/index.tsx +1 -0
  100. package/src/utils/constants.ts +43 -42
  101. package/src/utils/exportPdf.ts +3 -5
  102. package/src/utils/hooks/useInitialLayersVisiblity.tsx +1 -1
  103. package/src/utils/hooks/useLayerConfig.tsx +2 -2
  104. package/src/utils/hooks/useLayersConfig.tsx +3 -3
  105. package/src/utils/hooks/useMapContext.tsx +67 -8
  106. package/src/utils/hooks/useRvfContext.tsx +0 -44
  107. package/src/NotificationLayer/index.tsx +0 -1
  108. package/src/RvfEmbedNavigation/DragPanWarning.ts +0 -124
  109. package/src/RvfEmbedNavigation/RvfEmbedNavigation.tsx +0 -51
  110. package/src/RvfEmbedNavigation/index.js +0 -1
  111. package/src/RvfExportMenu/index.tsx +0 -1
  112. package/src/RvfExportMenuButton/index.tsx +0 -1
  113. package/src/RvfFloatingMenu/RvfFloatingMenu.tsx +0 -44
  114. package/src/RvfFloatingMenu/index.tsx +0 -1
  115. package/src/RvfLayerTreeButton/index.tsx +0 -1
  116. package/src/RvfLineNetworkPlanLayer/index.tsx +0 -1
  117. package/src/RvfPermalink/RvfPermalink.tsx +0 -18
  118. package/src/RvfPermalink/index.tsx +0 -1
  119. package/src/RvfSearchButton/index.tsx +0 -1
  120. package/src/RvfShare/RvfPermalinkButton/index.tsx +0 -1
  121. package/src/RvfShare/index.tsx +0 -1
  122. package/src/RvfShareMenuButton/index.tsx +0 -1
  123. package/src/RvfTopics/index.tsx +0 -1
  124. package/src/RvfZoomButtons/index.tsx +0 -1
@@ -1,15 +1,18 @@
1
1
  import { debounceDeparturesMessages } from "mobility-toolbox-js/ol";
2
2
  import { memo } from "preact/compat";
3
3
  import { useEffect, useRef, useState } from "preact/hooks";
4
+ import { twMerge } from "tailwind-merge";
4
5
 
5
6
  import Departure from "../Departure";
6
7
  import StationHeader from "../StationHeader";
7
8
  import useMapContext from "../utils/hooks/useMapContext";
8
9
 
9
10
  import type { RealtimeDeparture } from "mobility-toolbox-js/types";
10
- import type { JSX, PreactDOMAttributes } from "preact";
11
+ import type { HTMLAttributes, PreactDOMAttributes } from "preact";
11
12
 
12
- export type StationProps = JSX.HTMLAttributes<HTMLDivElement> &
13
+ export type StationProps = {
14
+ className?: string;
15
+ } & HTMLAttributes<HTMLDivElement> &
13
16
  PreactDOMAttributes;
14
17
 
15
18
  function Station(props: StationProps) {
@@ -48,7 +51,11 @@ function Station(props: StationProps) {
48
51
  return (
49
52
  <>
50
53
  <StationHeader />
51
- <div className={className} ref={ref}>
54
+ <div
55
+ className={twMerge("flex flex-col p-2", className)}
56
+ ref={ref}
57
+ {...props}
58
+ >
52
59
  {(departures || [])
53
60
  // .filter(hideDepartures)
54
61
  .map((departure: RealtimeDeparture, index: number) => {
@@ -28,7 +28,6 @@ function StationsLayer(props: Partial<MaplibreStyleLayerOptions>) {
28
28
  if (!map || !layer) {
29
29
  return;
30
30
  }
31
-
32
31
  map.addLayer(layer);
33
32
  setStationsLayer(layer);
34
33
 
@@ -13,6 +13,7 @@ import { twMerge } from "tailwind-merge";
13
13
  import Cancel from "../icons/Cancel";
14
14
  import Search from "../icons/Search";
15
15
  import IconButton from "../ui/IconButton";
16
+ import Input from "../ui/Input";
16
17
  import useI18n from "../utils/hooks/useI18n";
17
18
  import MobilityEvent from "../utils/MobilityEvent";
18
19
 
@@ -242,13 +243,12 @@ function StopsSearch({
242
243
  inputContainerClassName,
243
244
  )}
244
245
  >
245
- <input
246
+ <Input
246
247
  autoComplete="off"
247
248
  className={twMerge(
248
- "h-8 flex-1 overflow-hidden text-ellipsis outline-0 placeholder:text-zinc-400",
249
+ "h-8 w-1 grow overflow-hidden text-ellipsis placeholder:text-zinc-400",
249
250
  inputClassName,
250
251
  )}
251
- id="searchfield"
252
252
  onChange={(evt) => {
253
253
  // @ts-expect-error target is missing
254
254
  setQuery(evt.target.value);
@@ -333,7 +333,6 @@ function StopsSearch({
333
333
  )}
334
334
  </div>
335
335
  )}
336
- {/* </div> */}
337
336
  </>
338
337
  );
339
338
  }
@@ -1 +1,2 @@
1
- export { default, SearchProps, StationFeature } from "./StopsSearch";
1
+ export { default } from "./StopsSearch";
2
+ export type { StopsFeature, StopsSearchProps } from "./StopsSearch";
@@ -25,7 +25,6 @@ function WindowMessageListener({ eventNode }: { eventNode: HTMLElement }) {
25
25
  useEffect(() => {
26
26
  const onMessage = (event) => {
27
27
  if (event.data.situations) {
28
- console.log("Setting preview situations", event.data.situations);
29
28
  setPreviewNotifications(event.data.situations);
30
29
  }
31
30
  };
@@ -47,6 +46,13 @@ function WindowMessageListener({ eventNode }: { eventNode: HTMLElement }) {
47
46
  // @ts-expect-error children is the react property
48
47
  delete evt.data.children;
49
48
  }
49
+ if (evt.type === "mwc:selectedfeature") {
50
+ // @ts-expect-error children is the react property
51
+ if (evt.data?.properties?.olGeometry) {
52
+ // @ts-expect-error children is the react property
53
+ delete evt.data.properties.olGeometry;
54
+ }
55
+ }
50
56
  window.parent?.postMessage({ data: evt.data, type: evt.type }, "*");
51
57
  };
52
58
  evtTypes.forEach((eventType) => {
@@ -7,7 +7,7 @@ import Plus from "../icons/Plus";
7
7
  import IconButton from "../ui/IconButton";
8
8
  import useMapContext from "../utils/hooks/useMapContext";
9
9
 
10
- function RvfZoomButtons() {
10
+ function ZoomButtons() {
11
11
  const { map } = useMapContext();
12
12
  const [isZoomInDisabled, setIsZoomInDisabled] = useState(false);
13
13
  const [isZoomOutDisabled, setIsZoomOutDisabled] = useState(false);
@@ -56,18 +56,15 @@ function RvfZoomButtons() {
56
56
 
57
57
  return (
58
58
  <>
59
- <IconButton
60
- disabled={isZoomInDisabled}
61
- Icon={Plus}
62
- onClick={handleZoomIn}
63
- />
64
- <IconButton
65
- disabled={isZoomOutDisabled}
66
- Icon={Minus}
67
- onClick={handleZoomOut}
68
- />
59
+ <IconButton disabled={isZoomInDisabled} onClick={handleZoomIn}>
60
+ <Plus />
61
+ </IconButton>
62
+
63
+ <IconButton disabled={isZoomOutDisabled} onClick={handleZoomOut}>
64
+ <Minus />
65
+ </IconButton>
69
66
  </>
70
67
  );
71
68
  }
72
69
 
73
- export default memo(RvfZoomButtons);
70
+ export default memo(ZoomButtons);
@@ -0,0 +1 @@
1
+ export { default } from "./ZoomButtons";
@@ -0,0 +1,41 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+
3
+
4
+ <!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
5
+ <svg
6
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
7
+ xmlns:cc="http://creativecommons.org/ns#"
8
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
9
+ xmlns:svg="http://www.w3.org/2000/svg"
10
+ xmlns="http://www.w3.org/2000/svg"
11
+ version="1.1"
12
+ width="100%"
13
+ height="100%"
14
+ viewBox="0 0 14 14"
15
+ id="svg2">
16
+ <metadata
17
+ id="metadata8">
18
+ <rdf:RDF>
19
+ <cc:Work
20
+ rdf:about="">
21
+ <dc:format>image/svg+xml</dc:format>
22
+ <dc:type
23
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
24
+ <dc:title></dc:title>
25
+ </cc:Work>
26
+ </rdf:RDF>
27
+ </metadata>
28
+ <defs
29
+ id="defs6" />
30
+ <rect
31
+ width="14"
32
+ height="14"
33
+ x="0"
34
+ y="0"
35
+ id="canvas"
36
+ style="fill:none;stroke:none;visibility:hidden" />
37
+ <path
38
+ d="m 14,8 0,1 -6,-1 0,3 2,2 0,1 L 7,13 4,14 4,13 6,11 6,8 0,9 0,8 6,5 6,2 C 6,1 6.22222,0 7,0 7.77777,0 8,1 8,2 l 0,3 z"
39
+ id="airport"
40
+ style="fill:#000000;fill-opacity:1;stroke:none" />
41
+ </svg>
@@ -1,4 +1,5 @@
1
1
  import { memo, useMemo } from "preact/compat";
2
+ import { twMerge } from "tailwind-merge";
2
3
 
3
4
  import type {
4
5
  AnchorHTMLAttributes,
@@ -14,7 +15,8 @@ export type ButtonProps = {
14
15
  ButtonHTMLAttributes &
15
16
  PreactDOMAttributes;
16
17
 
17
- const baseClasses = "flex";
18
+ const baseClasses =
19
+ "flex gap-2 items-center px-4 py-2 rounded-2xl border hover:border-black hover:not-disabled:cursor-pointer";
18
20
 
19
21
  export const themes = {
20
22
  primary: {
@@ -36,7 +38,12 @@ function Button({
36
38
  ...props
37
39
  }: ButtonProps) {
38
40
  const classes = useMemo(() => {
39
- return `${baseClasses} ${themes[theme].classes} ${selected ? themes[theme].selectedClasses : ""} ${className || ""}`;
41
+ return twMerge(
42
+ baseClasses,
43
+ themes[theme].classes,
44
+ selected ? themes[theme].selectedClasses : "",
45
+ className,
46
+ );
40
47
  }, [className, selected, theme]);
41
48
 
42
49
  if (href) {
@@ -0,0 +1,32 @@
1
+ import { memo } from "preact/compat";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ import ok from "../../icons/Ok/ok-grey.svg";
5
+
6
+ import type { InputHTMLAttributes } from "preact";
7
+
8
+ export type RvfCheckboxProps = {
9
+ checkedIconUrl?: string;
10
+ className?: string;
11
+ } & InputHTMLAttributes;
12
+
13
+ function Checkbox({ className, ...props }: RvfCheckboxProps) {
14
+ const checkedIconUrl = props.checkedIconUrl || ok;
15
+ return (
16
+ <input
17
+ checked={props.checked}
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`,
20
+ className,
21
+ )}
22
+ style={{
23
+ backgroundImage:
24
+ props.checked && !props.disabled ? `url('${checkedIconUrl}')` : "",
25
+ }}
26
+ {...props}
27
+ type="checkbox"
28
+ />
29
+ );
30
+ }
31
+
32
+ export default memo(Checkbox);
@@ -0,0 +1 @@
1
+ export { default } from "../../RvfCheckbox";
@@ -1,16 +1,22 @@
1
1
  import { memo, useMemo } from "preact/compat";
2
+ import { twMerge } from "tailwind-merge";
2
3
 
3
- import type { ButtonHTMLAttributes, PreactDOMAttributes } from "preact";
4
+ import type {
5
+ AnchorHTMLAttributes,
6
+ ButtonHTMLAttributes,
7
+ PreactDOMAttributes,
8
+ } from "preact";
4
9
 
5
10
  export type IconButtonProps = {
6
11
  className?: string;
7
12
  selected?: boolean;
8
13
  theme?: "primary" | "secondary";
9
- } & ButtonHTMLAttributes<HTMLButtonElement> &
14
+ } & AnchorHTMLAttributes &
15
+ ButtonHTMLAttributes &
10
16
  PreactDOMAttributes;
11
17
 
12
18
  const baseClasses =
13
- "flex size-9 items-center justify-center rounded-full bg-white p-1.5 shadow-lg";
19
+ "flex size-9 items-center justify-center rounded-full bg-white p-1.5 shadow-lg hover:not-disabled:cursor-pointer";
14
20
 
15
21
  export const themes = {
16
22
  primary: {
@@ -26,14 +32,28 @@ export const themes = {
26
32
  function IconButton({
27
33
  children,
28
34
  className,
35
+ href,
29
36
  selected = false,
30
37
  theme = "secondary",
31
38
  ...props
32
39
  }: IconButtonProps) {
33
40
  const classes = useMemo(() => {
34
- return `${baseClasses} ${themes[theme].classes} ${selected ? themes[theme].selectedClasses : ""} ${className || ""}`;
41
+ return twMerge(
42
+ baseClasses,
43
+ themes[theme].classes,
44
+ selected ? themes[theme].selectedClasses : "",
45
+ className,
46
+ );
35
47
  }, [className, selected, theme]);
36
48
 
49
+ if (href) {
50
+ return (
51
+ <a className={classes} href={href} {...props}>
52
+ {children}
53
+ </a>
54
+ );
55
+ }
56
+
37
57
  return (
38
58
  <button className={classes} {...props}>
39
59
  {children}
@@ -0,0 +1,17 @@
1
+ import { twMerge } from "tailwind-merge";
2
+
3
+ import type { InputHTMLAttributes, PreactDOMAttributes } from "preact";
4
+
5
+ export type InputProps = { className?: string } & InputHTMLAttributes &
6
+ PreactDOMAttributes;
7
+
8
+ function Input({ className, ...props }: InputProps) {
9
+ return (
10
+ <input
11
+ {...props}
12
+ className={twMerge("p-2 text-sm read-only:text-gray-400", className)}
13
+ />
14
+ );
15
+ }
16
+
17
+ export default Input;
@@ -0,0 +1 @@
1
+ export { default } from "./Input";
@@ -0,0 +1,86 @@
1
+ import { useId, useState } from "preact/hooks";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ import Copy from "../../icons/Copy";
5
+ import IconButton from "../IconButton";
6
+ import Input from "../Input";
7
+
8
+ import type {
9
+ HTMLAttributes,
10
+ InputHTMLAttributes,
11
+ PreactDOMAttributes,
12
+ } from "preact";
13
+
14
+ export type InputCopyProps = {
15
+ containerProps?: HTMLAttributes<HTMLDivElement> & PreactDOMAttributes;
16
+ tooltipProps?: HTMLAttributes<HTMLDivElement> & PreactDOMAttributes;
17
+ } & InputHTMLAttributes &
18
+ PreactDOMAttributes;
19
+
20
+ const emptyProps = {}; // avoid re-rendering
21
+
22
+ function InputCopy({
23
+ containerProps = emptyProps,
24
+ tooltipProps = emptyProps,
25
+ ...props
26
+ }: InputCopyProps) {
27
+ const [positionTooltip, setPositionTooltip] = useState<DOMRect>();
28
+ const [isTooptipShowed, setIsTooltipShowed] = useState(false);
29
+ const inputId = useId();
30
+
31
+ const handleCopyClick = (event) => {
32
+ setPositionTooltip(event.currentTarget.getBoundingClientRect());
33
+ void navigator.clipboard.writeText(window?.location.href).then(() => {
34
+ setIsTooltipShowed(true);
35
+ setTimeout(() => {
36
+ setIsTooltipShowed(false);
37
+ }, 1000);
38
+ });
39
+ (document.getElementById(inputId) as HTMLInputElement | null)?.select();
40
+ };
41
+
42
+ const handleInputFocus = () => {
43
+ (document.getElementById(inputId) as HTMLInputElement | null)?.select();
44
+ };
45
+
46
+ return (
47
+ <div
48
+ {...containerProps}
49
+ className={twMerge(
50
+ "relative flex items-center",
51
+ containerProps?.className,
52
+ )}
53
+ >
54
+ <Input
55
+ id={inputId}
56
+ onFocus={handleInputFocus}
57
+ readOnly
58
+ type="text"
59
+ {...props}
60
+ className={twMerge("h-full flex-1 border border-r-0", props?.className)}
61
+ />
62
+ <IconButton
63
+ className="h-full rounded-none border p-2 shadow-none"
64
+ onClick={handleCopyClick}
65
+ >
66
+ <Copy />
67
+ </IconButton>
68
+ <div
69
+ {...tooltipProps}
70
+ className={twMerge(
71
+ `fixed hidden rounded bg-gray-600 p-1 text-sm text-white`,
72
+ isTooptipShowed && "block",
73
+ tooltipProps?.className,
74
+ )}
75
+ style={{
76
+ left: positionTooltip?.left - 30,
77
+ top: positionTooltip?.top - 30,
78
+ }}
79
+ >
80
+ Kopiert!
81
+ </div>
82
+ </div>
83
+ );
84
+ }
85
+
86
+ export default InputCopy;
@@ -0,0 +1 @@
1
+ export { default } from "../../RvfInputCopy";
@@ -0,0 +1,24 @@
1
+ import ArrowDown from "../../icons/ArrowDown";
2
+
3
+ import type { HTMLAttributes, PreactDOMAttributes } from "preact";
4
+
5
+ export type RvfSelectProps = {
6
+ className?: string;
7
+ } & HTMLAttributes<HTMLSelectElement> &
8
+ PreactDOMAttributes;
9
+
10
+ function Select({ children, className, onChange }: RvfSelectProps) {
11
+ return (
12
+ <div className="text-grey relative flex items-center">
13
+ <select
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}`}
15
+ onChange={onChange}
16
+ >
17
+ {children}
18
+ </select>
19
+ <ArrowDown className="pointer-events-none absolute right-[8px]" />
20
+ </div>
21
+ );
22
+ }
23
+
24
+ export default Select;
@@ -0,0 +1 @@
1
+ export { default } from "../../RvfSelect";
@@ -13,46 +13,49 @@ import type { FeatureCollection } from "geojson";
13
13
 
14
14
  export const LAYER_NAME_REALTIME = "echtzeit";
15
15
  export const LAYER_NAME_STATIONS = "haltestellen";
16
- export const LAYER_NAME_NOTIFICATION = "meldungen";
16
+ export const LAYER_NAME_NOTIFICATIONS = "meldungen";
17
+ export const LAYER_NAME_LINESNETWORKPLAN = "liniennetz";
17
18
 
18
19
  export const RVF_EXTENT_4326 = [7.5, 47.7, 8.45, 48.4];
19
20
 
20
- export const RVF_EXTENT_3857 = transformExtent(
21
+ export const MAX_EXTENT = transformExtent(
21
22
  RVF_EXTENT_4326,
22
23
  "EPSG:4326",
23
24
  "EPSG:3857",
24
25
  );
25
26
 
27
+ export const RVF_EXTENT_3857 = MAX_EXTENT;
28
+
26
29
  // @ts-expect-error - testsdsd sd
27
30
  window.fromLonLat = fromLonLat;
28
31
  // @ts-expect-error - testsdsd sd
29
32
  window.toLonLat = toLonLat;
30
33
  export const LAYER_PROP_IS_EXPORTING = "isExporting";
31
34
 
32
- export const RVF_LAYERS_TITLES = {
35
+ export const LAYERS_TITLES = {
33
36
  auto: "Auto",
34
37
  autoandere: "Auto, andere Anbieter",
35
38
  cargobike: "Cargobike",
36
39
  cargobikeandere: "Lastenrad, andere Anbieter",
37
40
  cargobikefrelo: "Lastenfrelo",
38
41
  "e-roller": "E-Roller",
39
- echtzeit: "Echtzeit",
40
42
  eroller: "E-Roller",
41
43
  fahrrad: "Fahrrad",
42
44
  fahrradandere: "Fahrrad, andere Anbieter",
43
45
  grueneflotte: "Grüne Flotte",
44
- haltestellen: "Haltestellen",
45
- liniennetz: "Liniennetz",
46
- meldungen: "Meldungen",
46
+ linesnetworkplan: "Liniennetz",
47
47
  mitfahrpunkte: "Mitfahrpunkte",
48
48
  naturenergie: "Naturenergie-Sharing",
49
+ notifications: "Meldungen",
49
50
  pois: "POIs",
51
+ realtime: "Echtzeit",
50
52
  sharedMobility: "Shared Mobility",
53
+ stations: "Haltestellen",
51
54
  tarifzonen: "Tarifzonen",
52
55
  verkaufsstellen: "Verkaufsstellen",
53
56
  };
54
57
 
55
- export const RVF_LAYERS_NAMES = {
58
+ export const LAYERS_NAMES = {
56
59
  bikeFrelo: "fahrradfrelo",
57
60
  bikeOthers: "fahrradandere",
58
61
  cargobikeFrelo: "cargobikefrelo",
@@ -60,37 +63,35 @@ export const RVF_LAYERS_NAMES = {
60
63
  carGrf: "grueneflotte",
61
64
  carNatur: "naturenergie",
62
65
  carOthers: "autoandere",
63
- echtzeit: LAYER_NAME_REALTIME,
64
66
  eroller: "e-roller",
65
- haltestellen: LAYER_NAME_STATIONS,
66
- liniennetz: "liniennetz",
67
- meldungen: LAYER_NAME_NOTIFICATION,
67
+ linesnetworkplan: LAYER_NAME_LINESNETWORKPLAN,
68
68
  mitfahrpunkte: "mitfahrpunkte",
69
+ notifications: LAYER_NAME_NOTIFICATIONS,
69
70
  pois: "pois",
71
+ realtime: LAYER_NAME_REALTIME,
72
+ stations: LAYER_NAME_STATIONS,
70
73
  tarifzonen: "tarifzonen",
71
74
  verkaufsstellen: "verkaufsstellen",
72
75
  };
73
76
 
74
- export const DEFAULT_QUERYABLE_LAYERS = Object.values(RVF_LAYERS_NAMES)
75
- .filter((name) => {
77
+ export const DEFAULT_QUERYABLE_LAYERS = Object.values(LAYERS_NAMES).filter(
78
+ (name) => {
76
79
  return ![
77
- RVF_LAYERS_NAMES.haltestellen,
78
- RVF_LAYERS_NAMES.mitfahrpunkte,
79
- RVF_LAYERS_NAMES.pois,
80
- RVF_LAYERS_NAMES.tarifzonen,
80
+ LAYERS_NAMES.mitfahrpunkte,
81
+ LAYERS_NAMES.pois,
82
+ LAYERS_NAMES.stations,
83
+ LAYERS_NAMES.tarifzonen,
81
84
  ].includes(name);
82
- })
83
- .toString();
84
-
85
- export const LAYERS_WITH_LINK = Object.values(RVF_LAYERS_NAMES)
86
- .filter((name) => {
87
- return (
88
- name !== RVF_LAYERS_NAMES.tarifzonen &&
89
- name !== RVF_LAYERS_NAMES.pois &&
90
- name !== RVF_LAYERS_NAMES.echtzeit
91
- );
92
- })
93
- .toString();
85
+ },
86
+ );
87
+
88
+ export const LAYERS_WITH_LINK = Object.values(LAYERS_NAMES).filter((name) => {
89
+ return (
90
+ name !== LAYERS_NAMES.tarifzonen &&
91
+ name !== LAYERS_NAMES.pois &&
92
+ name !== LAYERS_NAMES.realtime
93
+ );
94
+ });
94
95
 
95
96
  export const WFS_CARGO_BIKE_TYPE = "sharing_stations_cargo_bicycle";
96
97
  export const WFS_CAR_TYPE = "sharing_stations_car";
@@ -128,21 +129,21 @@ export const API_REQUEST_FEATURE_TYPE = {
128
129
  };
129
130
 
130
131
  export const TITLE_BY_FEED_ID = {
131
- callabike_ice: RVF_LAYERS_TITLES.fahrrad,
132
- flinkster_carsharing: RVF_LAYERS_TITLES.auto,
133
- "gruene-flotte_freiburg": RVF_LAYERS_TITLES.auto,
134
- lastenvelo_fr: RVF_LAYERS_TITLES.cargobike,
135
- naturenergie_sharing: RVF_LAYERS_TITLES.auto,
136
- nextbike_df: RVF_LAYERS_TITLES.fahrrad,
137
- yoio_freiburg: RVF_LAYERS_TITLES.eroller,
138
- zeus_freiburg: RVF_LAYERS_TITLES.eroller,
132
+ callabike_ice: LAYERS_TITLES.fahrrad,
133
+ flinkster_carsharing: LAYERS_TITLES.auto,
134
+ "gruene-flotte_freiburg": LAYERS_TITLES.auto,
135
+ lastenvelo_fr: LAYERS_TITLES.cargobike,
136
+ naturenergie_sharing: LAYERS_TITLES.auto,
137
+ nextbike_df: LAYERS_TITLES.fahrrad,
138
+ yoio_freiburg: LAYERS_TITLES.eroller,
139
+ zeus_freiburg: LAYERS_TITLES.eroller,
139
140
  };
140
141
 
141
142
  export const TITLE_BY_CATEGORY = {
142
- "Bike Sharing": RVF_LAYERS_TITLES.fahrrad,
143
- "Cargo Bike Sharing": RVF_LAYERS_TITLES.cargobike,
144
- "Car Sharing": RVF_LAYERS_TITLES.auto,
145
- "E-Scooter": RVF_LAYERS_TITLES.eroller,
143
+ "Bike Sharing": LAYERS_TITLES.fahrrad,
144
+ "Cargo Bike Sharing": LAYERS_TITLES.cargobike,
145
+ "Car Sharing": LAYERS_TITLES.auto,
146
+ "E-Scooter": LAYERS_TITLES.eroller,
146
147
  };
147
148
 
148
149
  export const PROVIDER_BY_FEED_ID = {
@@ -4,8 +4,6 @@ import { Map } from "ol";
4
4
  import { getBottomRight, getTopLeft } from "ol/extent";
5
5
  import View from "ol/View";
6
6
 
7
- import { RVF_EXTENT_3857 } from "./constants";
8
-
9
7
  import type { jsPDFOptions } from "jspdf";
10
8
  import type { Coordinate } from "ol/coordinate";
11
9
  import type { Extent } from "ol/extent";
@@ -532,12 +530,12 @@ export interface CopyrightExportOptions {
532
530
 
533
531
  export interface MapExportOptions {
534
532
  copyrightOptions?: CopyrightExportOptions;
533
+ maxExtent?: number[];
535
534
  onAfter?: (map: Map, layers: BaseLayer[]) => void;
536
535
  onBefore?: (map: Map, layers: BaseLayer[]) => void;
537
536
  pixelRatio?: number;
538
537
  text?: string;
539
538
  useCopyright?: boolean;
540
- useMaxExtent?: boolean;
541
539
  usePlaceholder?: boolean;
542
540
  }
543
541
 
@@ -547,11 +545,11 @@ async function exportPdf(
547
545
  mapExportOptions: MapExportOptions = {},
548
546
  ): Promise<boolean> {
549
547
  const {
548
+ maxExtent,
550
549
  onAfter,
551
550
  onBefore,
552
551
  pixelRatio = 3,
553
552
  useCopyright = true,
554
- useMaxExtent = false,
555
553
  usePlaceholder = true,
556
554
  } = mapExportOptions;
557
555
 
@@ -560,7 +558,7 @@ async function exportPdf(
560
558
  const size = sizePt.map((n) => {
561
559
  return (n * 96) / 72;
562
560
  });
563
- const extent = useMaxExtent ? RVF_EXTENT_3857 : null; //map.getView().calculateExtent();
561
+ const extent = maxExtent;
564
562
 
565
563
  // Save current pixel ratio
566
564
  const actualPixelRatio = window.devicePixelRatio;
@@ -1,8 +1,8 @@
1
+ import { getLayersAsFlatArray } from "mobility-toolbox-js/ol";
1
2
  import { unByKey } from "ol/Observable";
2
3
  import { useEffect } from "preact/hooks";
3
4
 
4
5
  import applyInitialLayerVisibility from "../applyInitialLayerVisibility";
5
- import getLayersAsFlatArray from "../getLayersAsFlatArray";
6
6
 
7
7
  import type { Map } from "ol";
8
8
 
@@ -1,4 +1,4 @@
1
- import { RVF_LAYERS_TITLES } from "../constants";
1
+ import { LAYERS_TITLES } from "../constants";
2
2
 
3
3
  import useLayersConfig from "./useLayersConfig";
4
4
 
@@ -10,7 +10,7 @@ function useLayerConfig(layerName: string) {
10
10
  // Set defaultstyle if not present in layersconfig
11
11
  const layerConfig = layersConfig[layerName] || ({} as LayerConfig);
12
12
  if (!layerConfig.title) {
13
- layerConfig.title = RVF_LAYERS_TITLES[layerName];
13
+ layerConfig.title = LAYERS_TITLES[layerName];
14
14
  }
15
15
 
16
16
  return layerConfig;