@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.
- package/CHANGELOG.md +52 -0
- package/docutils.js +198 -0
- package/index.html +48 -217
- package/index.js +680 -87
- package/input.css +11 -1
- package/jest-setup.js +3 -2
- package/package.json +4 -3
- package/scripts/build.mjs +3 -2
- package/scripts/dev.mjs +2 -1
- package/search.html +38 -69
- package/src/BaseLayer/BaseLayer.tsx +20 -12
- package/src/FloatingMenu/FloatingMenu.tsx +42 -0
- package/src/FloatingMenu/index.tsx +1 -0
- package/src/GeolocationButton/GeolocationButton.tsx +6 -5
- package/src/Map/Map.tsx +1 -0
- package/src/MobilityMap/MobilityMap.tsx +10 -9
- package/src/MobilityMap/index.css +0 -13
- package/src/RealtimeLayer/RealtimeLayer.tsx +2 -3
- package/src/RvfButton/RvfButton.tsx +28 -21
- package/src/RvfCheckbox/RvfCheckbox.tsx +24 -0
- package/src/RvfCheckbox/index.tsx +1 -0
- package/src/RvfExportMenu/RvfExportMenu.tsx +103 -0
- package/src/RvfExportMenu/index.tsx +1 -0
- package/src/RvfExportMenuButton/RvfExportMenuButton.tsx +27 -0
- package/src/RvfExportMenuButton/index.tsx +1 -0
- package/src/RvfFeatureDetails/RvfFeatureDetails.tsx +29 -0
- package/src/RvfFeatureDetails/index.tsx +1 -0
- package/src/RvfFloatingMenu/RvfFloatingMenu.tsx +44 -0
- package/src/RvfFloatingMenu/index.tsx +1 -0
- package/src/RvfIconButton/RvfIconButton.tsx +35 -0
- package/src/RvfIconButton/index.tsx +1 -0
- package/src/RvfLayerTree/RvfLayerTree.tsx +41 -0
- package/src/RvfLayerTree/TreeItem/TreeItem.tsx +120 -0
- package/src/RvfLayerTree/TreeItem/index.tsx +1 -0
- package/src/RvfLayerTree/index.tsx +1 -0
- package/src/RvfLayerTree/layersTreeContext.ts +4 -0
- package/src/RvfLayerTree/layersTreeReducer.ts +152 -0
- package/src/RvfLineNetworkPlanLayer/RvfLineNetworkPlanLayer.tsx +42 -0
- package/src/RvfLineNetworkPlanLayer/index.tsx +1 -0
- package/src/RvfMobilityMap/RvfMobilityMap.tsx +122 -83
- package/src/RvfMobilityMap/index.css +0 -13
- package/src/RvfModal/RvfModal.tsx +52 -0
- package/src/RvfModal/index.tsx +1 -0
- package/src/RvfPoisLayer/RvfPoisLayer.tsx +39 -0
- package/src/RvfPoisLayer/index.tsx +1 -0
- package/src/RvfRadioButton/RvfRadioButton.tsx +16 -0
- package/src/RvfRadioButton/index.tsx +1 -0
- package/src/RvfSelect/RvfSelect.tsx +22 -0
- package/src/RvfSelect/index.tsx +1 -0
- package/src/RvfSellingPointsLayer/RvfSellingPointsLayer.tsx +41 -0
- package/src/RvfSellingPointsLayer/index.tsx +1 -0
- package/src/RvfSharedMobilityLayerGroup/RvfSharedMobilityLayerGroup.tsx +100 -0
- package/src/RvfSharedMobilityLayerGroup/index.tsx +1 -0
- package/src/RvfSingleClickListener/RvfSingleClickListener.tsx +146 -0
- package/src/RvfSingleClickListener/index.tsx +1 -0
- package/src/RvfTarifZonenLayer/RvfTarifZonenLayer.tsx +41 -0
- package/src/RvfTarifZonenLayer/index.tsx +1 -0
- package/src/RvfTopics/RvfTopics.tsx +47 -0
- package/src/RvfTopics/index.tsx +1 -0
- package/src/RvfZoomButtons/RvfZoomButtons.tsx +36 -29
- package/src/Search/Search.tsx +11 -9
- package/src/SingleClickListener/index.tsx +1 -1
- package/src/StationsLayer/StationsLayer.tsx +0 -1
- package/src/StopsSearch/StopsSearch.tsx +38 -6
- package/src/icons/ArrowDown/ArrowDown.tsx +22 -0
- package/src/icons/ArrowDown/down-open.svg +7 -0
- package/src/icons/ArrowDown/index.tsx +1 -0
- package/src/icons/ArrowUp/ArrowUp.tsx +22 -0
- package/src/icons/ArrowUp/index.tsx +1 -0
- package/src/icons/ArrowUp/up-open.svg +7 -0
- package/src/icons/Bicycle/verkehrstraeger-rad-2px-white.svg +19 -0
- package/src/icons/Cancel/Cancel.tsx +21 -0
- package/src/icons/Cancel/cancel.svg +7 -0
- package/src/icons/Cancel/index.tsx +1 -0
- package/src/icons/Car/verkehrstraeger-auto-2px-white.svg +14 -0
- package/src/icons/CargoBicycle/verkehrstraeger-lastenrad-2px-white.svg +27 -0
- package/src/icons/DownOpen/DownOpen.tsx +24 -0
- package/src/icons/DownOpen/down-open.svg +7 -0
- package/src/icons/DownOpen/index.tsx +1 -0
- package/src/icons/Download/Download.tsx +20 -0
- package/src/icons/Download/download.svg +15 -0
- package/src/icons/Download/index.tsx +1 -0
- package/src/icons/Elevator/Elevator.tsx +1 -1
- package/src/icons/Menu/Menu.tsx +32 -0
- package/src/icons/Menu/index.tsx +1 -0
- package/src/icons/Menu/menu.svg +9 -0
- package/src/icons/Ok/ok-grey.svg +7 -0
- package/src/icons/Ok/ok.svg +4 -0
- package/src/icons/Scooter/scooter.svg +10 -0
- package/src/utils/constants.ts +9 -0
- package/src/utils/createMobiDataBwWfsLayer.ts +120 -0
- package/src/utils/createSharedMobilityLayer.ts +165 -0
- package/src/utils/exportPdf.ts +657 -0
- package/src/utils/hooks/useRvfContext.tsx +37 -0
- package/src/utils/hooks/useUpdatePermalink.tsx +2 -9
- package/tailwind.config.mjs +41 -19
- package/src/RvfSharedMobilityLayer/RvfSharedMobilityLayer.tsx +0 -147
- 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
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.
|
|
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.
|
|
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
|
-
|
|
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:
|
|
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
|
-
<script
|
|
54
|
-
type="module"
|
|
55
|
-
src="https://www.unpkg.com/@geops/mobility-web-component">
|
|
56
|
-
</script>
|
|
57
|
-
<geops-mobility-search
|
|
58
|
-
apikey="YOUR_GEOPS_API_KEY"
|
|
59
|
-
limit="5"
|
|
60
|
-
mots="rail,bus"
|
|
61
|
-
style="display: block;width: 800px;height: 800px;">
|
|
62
|
-
</geops-mobility></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
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
-
|
|
8
|
+
export type BaseLayerProps = MaplibreLayerOptions;
|
|
9
|
+
|
|
10
|
+
function BaseLayer(props: BaseLayerProps) {
|
|
10
11
|
const { apikey, baselayer, map, mapsurl, setBaseLayer } = useMapContext();
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
const layer = useMemo(() => {
|
|
14
|
+
if (!baselayer || !apikey) {
|
|
13
15
|
return;
|
|
14
16
|
}
|
|
15
|
-
|
|
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
|
-
|
|
24
|
+
}, [baselayer, apikey, props, mapsurl]);
|
|
22
25
|
|
|
23
|
-
|
|
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
|
|
37
|
+
map.removeLayer(layer);
|
|
30
38
|
};
|
|
31
|
-
}, [map,
|
|
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
|
|
9
|
-
import
|
|
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
|
-
<
|
|
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
|
@@ -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
|
-
|
|
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
|
|
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
|
|
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
|
|
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 />
|
|
@@ -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,
|
|
3
|
+
import { memo, useMemo } from "preact/compat";
|
|
4
4
|
|
|
5
|
-
export type RvfButtonProps =
|
|
6
|
-
|
|
5
|
+
export type RvfButtonProps = {
|
|
6
|
+
selected?: boolean;
|
|
7
|
+
theme?: "primary" | "secondary";
|
|
8
|
+
} & JSX.ButtonHTMLAttributes<HTMLButtonElement> &
|
|
7
9
|
PreactDOMAttributes;
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
theme,
|
|
30
|
+
selected = false,
|
|
31
|
+
theme = "secondary",
|
|
32
|
+
...props
|
|
21
33
|
}: RvfButtonProps) {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
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}
|
|
33
|
-
{children
|
|
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";
|