@geops/rvf-mobility-web-component 0.1.10 → 0.1.12

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 (98) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/docutils.js +198 -0
  3. package/index.html +48 -217
  4. package/index.js +680 -87
  5. package/input.css +11 -1
  6. package/jest-setup.js +3 -2
  7. package/package.json +4 -3
  8. package/scripts/build.mjs +3 -2
  9. package/scripts/dev.mjs +2 -1
  10. package/search.html +38 -69
  11. package/src/BaseLayer/BaseLayer.tsx +20 -12
  12. package/src/FloatingMenu/FloatingMenu.tsx +42 -0
  13. package/src/FloatingMenu/index.tsx +1 -0
  14. package/src/GeolocationButton/GeolocationButton.tsx +6 -5
  15. package/src/Map/Map.tsx +1 -0
  16. package/src/MobilityMap/MobilityMap.tsx +10 -9
  17. package/src/MobilityMap/index.css +0 -13
  18. package/src/RealtimeLayer/RealtimeLayer.tsx +2 -3
  19. package/src/RvfButton/RvfButton.tsx +28 -21
  20. package/src/RvfCheckbox/RvfCheckbox.tsx +24 -0
  21. package/src/RvfCheckbox/index.tsx +1 -0
  22. package/src/RvfExportMenu/RvfExportMenu.tsx +103 -0
  23. package/src/RvfExportMenu/index.tsx +1 -0
  24. package/src/RvfExportMenuButton/RvfExportMenuButton.tsx +27 -0
  25. package/src/RvfExportMenuButton/index.tsx +1 -0
  26. package/src/RvfFeatureDetails/RvfFeatureDetails.tsx +29 -0
  27. package/src/RvfFeatureDetails/index.tsx +1 -0
  28. package/src/RvfFloatingMenu/RvfFloatingMenu.tsx +44 -0
  29. package/src/RvfFloatingMenu/index.tsx +1 -0
  30. package/src/RvfIconButton/RvfIconButton.tsx +35 -0
  31. package/src/RvfIconButton/index.tsx +1 -0
  32. package/src/RvfLayerTree/RvfLayerTree.tsx +41 -0
  33. package/src/RvfLayerTree/TreeItem/TreeItem.tsx +120 -0
  34. package/src/RvfLayerTree/TreeItem/index.tsx +1 -0
  35. package/src/RvfLayerTree/index.tsx +1 -0
  36. package/src/RvfLayerTree/layersTreeContext.ts +4 -0
  37. package/src/RvfLayerTree/layersTreeReducer.ts +152 -0
  38. package/src/RvfLineNetworkPlanLayer/RvfLineNetworkPlanLayer.tsx +42 -0
  39. package/src/RvfLineNetworkPlanLayer/index.tsx +1 -0
  40. package/src/RvfMobilityMap/RvfMobilityMap.tsx +122 -83
  41. package/src/RvfMobilityMap/index.css +0 -13
  42. package/src/RvfModal/RvfModal.tsx +52 -0
  43. package/src/RvfModal/index.tsx +1 -0
  44. package/src/RvfPoisLayer/RvfPoisLayer.tsx +39 -0
  45. package/src/RvfPoisLayer/index.tsx +1 -0
  46. package/src/RvfRadioButton/RvfRadioButton.tsx +16 -0
  47. package/src/RvfRadioButton/index.tsx +1 -0
  48. package/src/RvfSelect/RvfSelect.tsx +22 -0
  49. package/src/RvfSelect/index.tsx +1 -0
  50. package/src/RvfSellingPointsLayer/RvfSellingPointsLayer.tsx +41 -0
  51. package/src/RvfSellingPointsLayer/index.tsx +1 -0
  52. package/src/RvfSharedMobilityLayerGroup/RvfSharedMobilityLayerGroup.tsx +100 -0
  53. package/src/RvfSharedMobilityLayerGroup/index.tsx +1 -0
  54. package/src/RvfSingleClickListener/RvfSingleClickListener.tsx +146 -0
  55. package/src/RvfSingleClickListener/index.tsx +1 -0
  56. package/src/RvfTarifZonenLayer/RvfTarifZonenLayer.tsx +41 -0
  57. package/src/RvfTarifZonenLayer/index.tsx +1 -0
  58. package/src/RvfTopics/RvfTopics.tsx +47 -0
  59. package/src/RvfTopics/index.tsx +1 -0
  60. package/src/RvfZoomButtons/RvfZoomButtons.tsx +36 -29
  61. package/src/Search/Search.tsx +11 -9
  62. package/src/SingleClickListener/index.tsx +1 -1
  63. package/src/StationsLayer/StationsLayer.tsx +0 -1
  64. package/src/StopsSearch/StopsSearch.tsx +38 -6
  65. package/src/icons/ArrowDown/ArrowDown.tsx +22 -0
  66. package/src/icons/ArrowDown/down-open.svg +7 -0
  67. package/src/icons/ArrowDown/index.tsx +1 -0
  68. package/src/icons/ArrowUp/ArrowUp.tsx +22 -0
  69. package/src/icons/ArrowUp/index.tsx +1 -0
  70. package/src/icons/ArrowUp/up-open.svg +7 -0
  71. package/src/icons/Bicycle/verkehrstraeger-rad-2px-white.svg +19 -0
  72. package/src/icons/Cancel/Cancel.tsx +21 -0
  73. package/src/icons/Cancel/cancel.svg +7 -0
  74. package/src/icons/Cancel/index.tsx +1 -0
  75. package/src/icons/Car/verkehrstraeger-auto-2px-white.svg +14 -0
  76. package/src/icons/CargoBicycle/verkehrstraeger-lastenrad-2px-white.svg +27 -0
  77. package/src/icons/DownOpen/DownOpen.tsx +24 -0
  78. package/src/icons/DownOpen/down-open.svg +7 -0
  79. package/src/icons/DownOpen/index.tsx +1 -0
  80. package/src/icons/Download/Download.tsx +20 -0
  81. package/src/icons/Download/download.svg +15 -0
  82. package/src/icons/Download/index.tsx +1 -0
  83. package/src/icons/Elevator/Elevator.tsx +1 -1
  84. package/src/icons/Menu/Menu.tsx +32 -0
  85. package/src/icons/Menu/index.tsx +1 -0
  86. package/src/icons/Menu/menu.svg +9 -0
  87. package/src/icons/Ok/ok-grey.svg +7 -0
  88. package/src/icons/Ok/ok.svg +4 -0
  89. package/src/icons/Scooter/scooter.svg +10 -0
  90. package/src/utils/constants.ts +9 -0
  91. package/src/utils/createMobiDataBwWfsLayer.ts +120 -0
  92. package/src/utils/createSharedMobilityLayer.ts +165 -0
  93. package/src/utils/exportPdf.ts +657 -0
  94. package/src/utils/hooks/useRvfContext.tsx +37 -0
  95. package/src/utils/hooks/useUpdatePermalink.tsx +2 -9
  96. package/tailwind.config.mjs +41 -19
  97. package/src/RvfSharedMobilityLayer/RvfSharedMobilityLayer.tsx +0 -147
  98. package/src/RvfSharedMobilityLayer/index.tsx +0 -1
package/input.css CHANGED
@@ -3,14 +3,18 @@
3
3
  @tailwind utilities;
4
4
 
5
5
  ::-webkit-scrollbar {
6
- height: 3px;
7
6
  width: 3px;
7
+ height: 3px;
8
8
  }
9
9
 
10
10
  ::-webkit-scrollbar-thumb {
11
11
  background: gray;
12
12
  }
13
13
 
14
+ ::-webkit-scrollbar-track {
15
+ background: transparent;
16
+ }
17
+
14
18
  html {
15
19
  @apply text-base;
16
20
  }
@@ -31,8 +35,14 @@ html {
31
35
  h4 {
32
36
  @apply text-lg;
33
37
  }
38
+ button {
39
+ @apply text-button font-semibold;
40
+ }
34
41
  }
35
42
 
36
43
  .button-map {
37
44
  @apply bg-blue-500 text-white;
45
+ background: lightgray;
46
+ z-index: 5;
38
47
  }
48
+
package/jest-setup.js CHANGED
@@ -1,4 +1,5 @@
1
- /* eslint-disable import/no-extraneous-dependencies */
2
1
  import "jest-canvas-mock";
3
2
 
4
- global.URL.createObjectURL = jest.fn(() => "fooblob");
3
+ global.URL.createObjectURL = jest.fn(() => {
4
+ return "fooblob";
5
+ });
package/package.json CHANGED
@@ -2,13 +2,14 @@
2
2
  "name": "@geops/rvf-mobility-web-component",
3
3
  "license": "UNLICENSED",
4
4
  "description": "Web components for rvf in the domains of mobility and logistics.",
5
- "version": "0.1.10",
5
+ "version": "0.1.12",
6
6
  "homepage": "https://rvf-mobility-web-component-geops.vercel.app/",
7
7
  "type": "module",
8
8
  "main": "index.js",
9
9
  "dependencies": {
10
+ "jspdf": "^2.5.2",
10
11
  "maplibre-gl": "^4.7.1",
11
- "mobility-toolbox-js": "3.0.0",
12
+ "mobility-toolbox-js": "3.1.0",
12
13
  "ol": "^10.3.1",
13
14
  "preact": "^10.25.1",
14
15
  "preact-custom-element": "^4.3.0",
@@ -70,7 +71,7 @@
70
71
  "publish:public:dryrun": "yarn release --dry-run",
71
72
  "release": "standard-version",
72
73
  "start": "concurrently \"yarn tailwind:component --watch\" \"yarn tailwind:website --watch\" \"yarn dev\"",
73
- "tailwind:component": "tailwindcss --output=src/style.css --content=src/**/*.tsx",
74
+ "tailwind:component": "tailwindcss --input=./input.css --output=src/style.css --content=src/**/*.tsx",
74
75
  "tailwind:website": "tailwindcss --input=./input.css --output=output.css --content=*.html --minify",
75
76
  "test": "TZ=UTC jest",
76
77
  "up": "yarn upgrade-interactive --latest",
package/scripts/build.mjs CHANGED
@@ -3,13 +3,14 @@ import * as esbuild from "esbuild";
3
3
  import { sassPlugin } from "esbuild-sass-plugin";
4
4
 
5
5
  await esbuild.build({
6
- entryPoints: ["./src/index.js"],
7
6
  bundle: true,
8
- minify: true,
7
+ entryPoints: ["./src/index.js"],
9
8
  external: ["mapbox-gl"],
10
9
  loader: {
11
10
  ".png": "dataurl",
11
+ ".svg": "dataurl",
12
12
  },
13
+ minify: true,
13
14
  outfile: "index.js",
14
15
  plugins: [sassPlugin({ type: "css-text" })],
15
16
  sourcemap: false,
package/scripts/dev.mjs CHANGED
@@ -3,11 +3,12 @@ import * as esbuild from "esbuild";
3
3
  import { sassPlugin } from "esbuild-sass-plugin";
4
4
 
5
5
  const ctx = await esbuild.context({
6
- entryPoints: ["./src/index.js"],
7
6
  bundle: true,
7
+ entryPoints: ["./src/index.js"],
8
8
  external: ["mapbox-gl"],
9
9
  loader: {
10
10
  ".png": "dataurl",
11
+ ".svg": "dataurl",
11
12
  },
12
13
  outfile: "index.js",
13
14
  plugins: [sassPlugin({ type: "css-text" })],
package/search.html CHANGED
@@ -16,17 +16,22 @@
16
16
  }
17
17
  </script>
18
18
  <script type="module" src="./index.js"></script>
19
+ <script src="./docutils.js"></script>
19
20
  <link rel="stylesheet" type="text/css" href="./output.css" />
20
21
  <style>
21
22
  ::-webkit-scrollbar {
22
- width: 10px;
23
+ width: 3px;
24
+ height: 3px;
23
25
  }
24
26
  a {
25
27
  text-decoration: underline;
26
28
  }
27
29
  </style>
28
30
  </head>
31
+ </head>
29
32
  <body class="p-8">
33
+ <!-- tailwind hack to add class used in docutils -->
34
+ <div class="border px-4 py-2 table-auto w-full flex gap-4 p-2 bg-black text-white hover:bg-gray-700" style="display:none;"></div>
30
35
  <div
31
36
  id="doc"
32
37
  style="display: none"
@@ -49,28 +54,19 @@
49
54
  </p>
50
55
 
51
56
  <h2 class="text-xl font-bold">Usage example</h2>
52
- <pre class="bg-slate-800 text-slate-200 p-4 rounded">
53
- &lt;script
54
- type=&quot;module&quot;
55
- src=&quot;https://www.unpkg.com/@geops/mobility-web-component&quot;&gt;
56
- &lt;/script&gt;
57
- &lt;geops-mobility-search
58
- apikey=&quot;YOUR_GEOPS_API_KEY&quot;
59
- limit=&quot;5&quot;
60
- mots=&quot;rail,bus&quot;
61
- style=&quot;display: block;width: 800px;height: 800px;&quot;&gt;
62
- &lt;/geops-mobility&gt;</pre
63
- >
57
+ <pre id="code" class="bg-slate-800 text-slate-200 p-4 rounded"></pre>
64
58
 
65
- <!-- Default -->
66
59
  <geops-mobility-search
67
60
  class="max-w-3xl block border"
68
61
  limit="5"
69
62
  mots="rail,bus"
70
63
  ></geops-mobility-search>
71
64
 
72
- <pre id="textarea" class="w-full h-96 p-2"></pre>
73
-
65
+ <br />
66
+ <h2 class="text-xl font-bold">Attributes</h2>
67
+ <div id="attributes"></div>
68
+ <h2 class="text-xl font-bold">Events</h2>
69
+ <div id="events"></div>
74
70
  <br />
75
71
  <br />
76
72
  <h1 class="text-xl font-bold">More mobility web components</h1>
@@ -80,65 +76,38 @@
80
76
  >
81
77
  </p>
82
78
  </div>
79
+ <br />
80
+ <br />
83
81
  <script type="text/javascript">
84
- let params = new URLSearchParams(window.location.search);
85
- const searchElement = document.querySelector("geops-mobility-search");
86
- const eventLog = document.querySelector("#textarea");
87
-
88
-
89
- // Listen window event
90
- window.addEventListener("message", (event) => {
91
- const { type } = event.data || {};
92
- console.log("message event: " + type, event.data);
93
- });
94
- </script>
95
-
96
- <script type="text/javascript">
97
- params = new URLSearchParams(window.location.search);
98
-
99
- // There should be only one webcompoennt on the html page at this point
100
- const doc = document.querySelectorAll("#doc");
82
+ const pkgSrc = "https://www.unpkg.com/@geops/mobility-web-component";
101
83
  const wc = document.querySelector("geops-mobility-search");
102
- if (params.get("fullscreen") === "true") {
103
- wc.parentElement.removeChild(wc);
104
- wc.className = "absolute w-full h-full inset-0";
105
- document.body.appendChild(wc);
106
- document.body.style = "padding:0;";
107
- } else {
108
- doc.forEach((d) => (d.style.display = "block"));
109
- }
110
- params.delete("fullscreen");
111
84
 
112
- // Apply all url parameters as attribute of the web component
113
- params.forEach((value, key) => {
114
- wc.setAttribute(key, value);
115
- });
116
-
117
- if (!wc.getAttribute("apikey")) {
118
- fetch("https://backend.developer.geops.io/publickey")
119
- .then((response) => response.json())
120
- .then((data) => {
121
- if (data && data.success) {
122
- wc.setAttribute("apikey", data.key);
123
- }
124
- });
125
- }
85
+ const attrs = [
86
+ "apikey",
87
+ "bbox",
88
+ "countrycode",
89
+ "event",
90
+ "field",
91
+ "limit",
92
+ "mots",
93
+ "onselect",
94
+ "params",
95
+ "prefagencies",
96
+ "reflocation",
97
+ "url",
98
+ ];
126
99
 
100
+ const events = [
101
+ "mwc:stopssearchselect",
102
+ ];
127
103
 
128
- // Listen to element event
129
- searchElement.addEventListener("mwc:stopssearchselect", (event) => {
130
- const data = event.data;
131
- if (!data) {
132
- eventLog.innerText = "";
133
- } else {
134
- eventLog.innerText =
135
- "Event " +
136
- event.type +
137
- " received :\n " +
138
- JSON.stringify(data, undefined, " ");
139
- window.top.postMessage(data, "*");
140
- }
104
+ document.querySelector('#attributes').innerHTML = generateAttributesTable(wc, attrs);
105
+ document.querySelector('#events').innerHTML = generateEventsTable(wc, events);
106
+ document.querySelector('#code').innerHTML = generateCodeText(wc, attrs, pkgSrc);
107
+ wc.addEventListener('mwc:attribute', (event) => {
108
+ document.querySelector('#code').innerHTML = generateCodeText(wc, attrs, pkgSrc);
141
109
  });
110
+ applyPermalinkParameters(wc);
142
111
  </script>
143
112
  </body>
144
113
  </html>
@@ -1,34 +1,42 @@
1
1
  import { MaplibreLayer } from "mobility-toolbox-js/ol";
2
2
  import { MaplibreLayerOptions } from "mobility-toolbox-js/ol/layers/MaplibreLayer";
3
- import { Layer } from "ol/layer";
4
3
  import { memo } from "preact/compat";
5
- import { useEffect } from "preact/hooks";
4
+ import { useEffect, useMemo } from "preact/hooks";
6
5
 
7
6
  import useMapContext from "../utils/hooks/useMapContext";
8
7
 
9
- function BaseLayer(props: MaplibreLayerOptions) {
8
+ export type BaseLayerProps = MaplibreLayerOptions;
9
+
10
+ function BaseLayer(props: BaseLayerProps) {
10
11
  const { apikey, baselayer, map, mapsurl, setBaseLayer } = useMapContext();
11
- useEffect(() => {
12
- if (!map || !baselayer || !apikey) {
12
+
13
+ const layer = useMemo(() => {
14
+ if (!baselayer || !apikey) {
13
15
  return;
14
16
  }
15
- const layer = new MaplibreLayer({
17
+ return new MaplibreLayer({
16
18
  apiKey: apikey,
17
19
  style: baselayer,
18
20
  url: mapsurl,
21
+ zIndex: 0,
19
22
  ...(props || {}),
20
23
  });
21
- const baseLayer = layer as unknown as Layer;
24
+ }, [baselayer, apikey, props, mapsurl]);
22
25
 
23
- // TODO: find why the setZIndex is not found
24
- baseLayer.setZIndex(0);
25
- map.addLayer(baseLayer);
26
+ useEffect(() => {
26
27
  setBaseLayer(layer);
28
+ }, [layer, setBaseLayer]);
29
+
30
+ useEffect(() => {
31
+ if (!map || !layer) {
32
+ return;
33
+ }
34
+ map.addLayer(layer);
27
35
 
28
36
  return () => {
29
- map?.removeLayer(baseLayer);
37
+ map.removeLayer(layer);
30
38
  };
31
- }, [map, baselayer, apikey, setBaseLayer, props, mapsurl]);
39
+ }, [map, layer]);
32
40
 
33
41
  return null;
34
42
  }
@@ -0,0 +1,42 @@
1
+ import { useState } from "preact/hooks";
2
+
3
+ import ArrowDown from "../icons/ArrowDown";
4
+ import ArrowUp from "../icons/ArrowUp";
5
+ import Topics from "../RvfTopics";
6
+ import useMapContext from "../utils/hooks/useMapContext";
7
+
8
+ function FloatingMenu() {
9
+ const { map } = useMapContext();
10
+ const [isCollapsed, setIsCollapsed] = useState(true);
11
+
12
+ if (!map) {
13
+ return null;
14
+ }
15
+
16
+ return (
17
+ <div className="pointer-events-none absolute bottom-8 left-2 top-2 z-10 flex flex-col overflow-hidden rounded-lg">
18
+ <div
19
+ className="pointer-events-auto max-h-full rounded-lg border bg-white shadow-lg medium:w-largeMenu large:w-mediumMenu"
20
+
21
+ // className="flex-column absolute left-2 top-2 z-10 max-h-80 rounded-lg bg-white px-2 py-1.5 shadow-lg medium:w-largeMenu large:w-mediumMenu"
22
+ >
23
+ <button
24
+ className="flex w-full items-center justify-between px-2 py-1.5 "
25
+ onClick={() => {
26
+ return setIsCollapsed(!isCollapsed);
27
+ }}
28
+ >
29
+ <span>Kartendaten</span>
30
+ {isCollapsed ? <ArrowDown /> : <ArrowUp />}
31
+ </button>
32
+ {!isCollapsed && (
33
+ <div className="flex h-[calc(100%-39px)] w-full flex-1 overflow-y-auto">
34
+ <Topics />
35
+ </div>
36
+ )}
37
+ </div>
38
+ </div>
39
+ );
40
+ }
41
+
42
+ export default FloatingMenu;
@@ -0,0 +1 @@
1
+ export { default } from "./FloatingMenu";
@@ -5,8 +5,8 @@ import { unByKey } from "ol/Observable";
5
5
  import { fromLonLat } from "ol/proj";
6
6
  import { useEffect, useMemo } from "preact/hooks";
7
7
 
8
- import GeoIcon from "../icons/Geolocation";
9
- import RvfButton from "../RvfButton";
8
+ import GeolocationIcon from "../icons/Geolocation";
9
+ import RvfIconButton from "../RvfIconButton";
10
10
  import useMapContext from "../utils/hooks/useMapContext";
11
11
 
12
12
  export type GeolocationButtonProps = JSX.HTMLAttributes<HTMLButtonElement> &
@@ -55,14 +55,15 @@ function GeolocationButton({ ...props }: GeolocationButtonProps) {
55
55
  }, [geolocation, isTracking]);
56
56
 
57
57
  return (
58
- <RvfButton
58
+ <RvfIconButton
59
59
  className={isTracking ? "animate-pulse" : ""}
60
- Icon={GeoIcon}
61
60
  onClick={() => {
62
61
  setIsTracking(!isTracking);
63
62
  }}
64
63
  {...props}
65
- />
64
+ >
65
+ <GeolocationIcon />
66
+ </RvfIconButton>
66
67
  );
67
68
  }
68
69
 
package/src/Map/Map.tsx CHANGED
@@ -55,6 +55,7 @@ function Map({ children, ...props }: RealtimeMapProps) {
55
55
  if (mapRef.current) {
56
56
  newMap = new OlMap({
57
57
  controls: [],
58
+ // pixelRatio: 3,
58
59
  target: mapRef.current,
59
60
  });
60
61
  setMap(newMap);
@@ -11,7 +11,7 @@ import {
11
11
  } from "mobility-toolbox-js/types";
12
12
  import { Map as OlMap } from "ol";
13
13
  import { memo } from "preact/compat";
14
- import { useEffect, useMemo, useState } from "preact/hooks";
14
+ import { useEffect, useMemo, useRef, useState } from "preact/hooks";
15
15
 
16
16
  import BaseLayer from "../BaseLayer";
17
17
  import Copyright from "../Copyright";
@@ -84,6 +84,7 @@ function MobilityMap({
84
84
  tenant = null,
85
85
  zoom = "13",
86
86
  }: MobilityMapProps) {
87
+ const eventNodeRef = useRef<HTMLDivElement>();
87
88
  const [baseLayer, setBaseLayer] = useState<MaplibreLayer>();
88
89
  const [isFollowing, setIsFollowing] = useState(false);
89
90
  const [isTracking, setIsTracking] = useState(false);
@@ -97,7 +98,7 @@ function MobilityMap({
97
98
 
98
99
  // TODO: this should be removed. The parent application should be responsible to do this
99
100
  // or we should find something that fit more usecases
100
- const { x, y, z } = useUpdatePermalink(map, permalink === "true");
101
+ useUpdatePermalink(map, permalink === "true");
101
102
 
102
103
  const mapContextValue = useMemo(() => {
103
104
  return {
@@ -175,10 +176,10 @@ function MobilityMap({
175
176
  ]);
176
177
 
177
178
  useEffect(() => {
178
- dispatchEvent(
179
+ eventNodeRef.current?.dispatchEvent(
179
180
  new MobilityEvent<MobilityMapProps>("mwc:attribute", {
180
181
  baselayer,
181
- center: x && y ? `${x},${y}` : center,
182
+ center,
182
183
  extent,
183
184
  geolocation,
184
185
  mapsurl,
@@ -194,7 +195,7 @@ function MobilityMap({
194
195
  realtimeurl,
195
196
  search,
196
197
  tenant,
197
- zoom: z || zoom,
198
+ zoom,
198
199
  }),
199
200
  );
200
201
  }, [
@@ -216,9 +217,6 @@ function MobilityMap({
216
217
  search,
217
218
  tenant,
218
219
  zoom,
219
- x,
220
- y,
221
- z,
222
220
  ]);
223
221
 
224
222
  return (
@@ -226,7 +224,10 @@ function MobilityMap({
226
224
  <style>{tailwind}</style>
227
225
  <style>{style}</style>
228
226
  <MapContext.Provider value={mapContextValue}>
229
- <div className="relative size-full border font-sans @container/main">
227
+ <div
228
+ className="relative size-full border font-sans @container/main"
229
+ ref={eventNodeRef}
230
+ >
230
231
  <div className="relative flex size-full flex-col @lg/main:flex-row-reverse">
231
232
  <Map className="relative flex-1 overflow-visible ">
232
233
  <BaseLayer />
@@ -1,13 +0,0 @@
1
- ::-webkit-scrollbar {
2
- width: 3px;
3
- height: 3px;
4
- }
5
-
6
- ::-webkit-scrollbar-thumb {
7
- background: lightgray;
8
- z-index: 5;
9
- }
10
-
11
- ::-webkit-scrollbar-track {
12
- background: transparent;
13
- }
@@ -16,7 +16,7 @@ import useMapContext from "../utils/hooks/useMapContext";
16
16
 
17
17
  const TRACKING_ZOOM = 16;
18
18
 
19
- export type RealtimeLayerProps = RealtimeLayerOptions;
19
+ export type RealtimeLayerProps = RealtimeLayerOptions & Record<string, unknown>;
20
20
 
21
21
  function RealtimeLayer(props: RealtimeLayerProps) {
22
22
  const {
@@ -50,6 +50,7 @@ function RealtimeLayer(props: RealtimeLayerProps) {
50
50
  : undefined,
51
51
  tenant,
52
52
  url: realtimeurl,
53
+ zIndex: 1,
53
54
  ...props,
54
55
  styleOptions: {
55
56
  getDelayColor: getDelayColorForVehicle,
@@ -61,8 +62,6 @@ function RealtimeLayer(props: RealtimeLayerProps) {
61
62
  },
62
63
  });
63
64
 
64
- layer.setZIndex(1);
65
-
66
65
  return layer;
67
66
  }, [apikey, mots, realtimeurl, tenant, props]);
68
67
 
@@ -1,36 +1,43 @@
1
1
  import type { JSX, PreactDOMAttributes } from "preact";
2
2
 
3
- import { memo, SVGProps } from "preact/compat";
3
+ import { memo, useMemo } from "preact/compat";
4
4
 
5
- export type RvfButtonProps = ButtonProps &
6
- JSX.ButtonHTMLAttributes<HTMLButtonElement> &
5
+ export type RvfButtonProps = {
6
+ selected?: boolean;
7
+ theme?: "primary" | "secondary";
8
+ } & JSX.ButtonHTMLAttributes<HTMLButtonElement> &
7
9
  PreactDOMAttributes;
8
10
 
9
- interface ButtonProps {
10
- Icon?: (props: SVGProps<SVGSVGElement>) => preact.JSX.Element;
11
- theme?: "primary" | "secondary";
12
- }
11
+ const baseClasses =
12
+ "flex h-8 md:h-9 lg:h-10 px-5 py-1.75 max-h-button items-center justify-center rounded-full border";
13
+
14
+ export const themes = {
15
+ primary: {
16
+ classes:
17
+ "border-red bg-red text-white disabled:bg-lightgrey disabled:border-lightgrey hover:bg-darkred hover:border-darkred active:bg-lightred active:border-lightred",
18
+ selectedClasses: "bg-darkred border-darkred",
19
+ },
20
+ secondary: {
21
+ classes:
22
+ "border border-current bg-white text-grey hover:text-red disabled:text-lightgrey active:text-lightred",
23
+ selectedClasses: "text-red",
24
+ },
25
+ };
13
26
 
14
27
  function RvfButton({
15
28
  children,
16
29
  className,
17
- disabled,
18
- Icon,
19
- onClick,
20
- theme,
30
+ selected = false,
31
+ theme = "secondary",
32
+ ...props
21
33
  }: RvfButtonProps) {
22
- const baseClasses =
23
- "flex h-8 w-8 md:h-9 md:w-9 lg:w-10 lg:h-10 p-1.75 max-w-button max-h-button items-center justify-center rounded-full border";
24
- const themeClasses =
25
- theme === "primary"
26
- ? "border-red bg-red text-white"
27
- : "border-grey bg-white text-grey";
28
-
29
- const classes = `${baseClasses} ${themeClasses} ${className || ""}`;
34
+ const classes = useMemo(() => {
35
+ return `${baseClasses} ${themes[theme].classes} ${selected ? themes[theme].selectedClasses : ""} ${className || ""}`;
36
+ }, [className, selected, theme]);
30
37
 
31
38
  return (
32
- <button className={classes} disabled={disabled} onClick={onClick}>
33
- {children || <Icon height={"100%"} width={"100%"} />}
39
+ <button className={classes} {...props}>
40
+ {children}
34
41
  </button>
35
42
  );
36
43
  }
@@ -0,0 +1,24 @@
1
+ import type { JSX } from "preact";
2
+
3
+ import { memo } from "preact/compat";
4
+
5
+ // @ts-expect-error - required for htm to resolve the JSX pragma
6
+ import ok from "../icons/Ok/ok-grey.svg";
7
+
8
+ export type RvfCheckboxProps = {} & JSX.InputHTMLAttributes<HTMLInputElement>;
9
+
10
+ function RvfCheckbox({ className, ...props }: RvfCheckboxProps) {
11
+ return (
12
+ <input
13
+ className={`box-border size-[20px] cursor-pointer appearance-none rounded border-2 border-grey bg-white bg-contain bg-center text-grey disabled:cursor-default disabled:border-lightgrey ${className}`}
14
+ style={{
15
+ backgroundImage:
16
+ props.checked && !props.disabled ? `url('` + ok + `')` : "",
17
+ }}
18
+ {...props}
19
+ type="checkbox"
20
+ />
21
+ );
22
+ }
23
+
24
+ export default memo(RvfCheckbox);
@@ -0,0 +1 @@
1
+ export { default } from "./RvfCheckbox";