@geops/rvf-mobility-web-component 0.1.56 → 0.1.58
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 +31 -0
- package/docutils.js +1 -1
- package/global.d.ts +1 -0
- package/iframe.html +15 -0
- package/index.html +2 -1
- package/index.js +278 -330
- package/package.json +16 -17
- package/src/{RvfExportMenu/RvfExportMenu.tsx → ExportMenu/ExportMenu.tsx} +11 -11
- package/src/ExportMenu/index.tsx +1 -0
- package/src/{RvfExportMenuButton/RvfExportMenuButton.tsx → ExportMenuButton/ExportMenuButton.tsx} +5 -5
- package/src/ExportMenuButton/index.tsx +1 -0
- package/src/FeatureDetails/FeatureDetails.tsx +57 -0
- package/src/FeatureDetails/index.ts +1 -0
- package/src/FeaturesInfosListener/FeaturesInfosListener.tsx +73 -0
- package/src/FeaturesInfosListener/index.tsx +1 -0
- package/src/GeolocationButton/GeolocationButton.tsx +0 -1
- package/src/LayerTree/LayerTree.tsx +58 -0
- package/src/LayerTree/TreeItem/TreeItem.tsx +151 -0
- package/src/LayerTree/TreeItem/index.tsx +1 -0
- package/src/LayerTree/index.tsx +1 -0
- package/src/LayerTree/layersTreeContext.ts +4 -0
- package/src/LayerTree/layersTreeReducer.ts +158 -0
- package/src/{RvfLayerTreeButton/RvfLayerTreeButton.tsx → LayerTreeButton/LayerTreeButton.tsx} +5 -5
- package/src/LayerTreeButton/index.tsx +1 -0
- package/src/{RvfTopics/RvfTopics.tsx → LayerTreeMenu/LayerTreeMenu.tsx} +17 -13
- package/src/LayerTreeMenu/index.tsx +1 -0
- package/src/LayoutState/LayoutState.tsx +277 -0
- package/src/LayoutState/index.tsx +1 -0
- package/src/LinesNetworkPlanDetails/LinesNetworkPlanDetails.tsx +292 -0
- package/src/LinesNetworkPlanDetails/index.tsx +1 -0
- package/src/{RvfLineNetworkPlanLayer/RvfLineNetworkPlanLayer.tsx → LinesNetworkPlanLayer/LinesNetworkPlanLayer.tsx} +7 -9
- package/src/LinesNetworkPlanLayer/index.tsx +1 -0
- package/src/MobilityMap/MobilityMap.tsx +274 -60
- package/src/MobilityMap/MobilityMapAttributes.ts +27 -43
- package/src/NotificationDetails/NotificationDetails.tsx +468 -0
- package/src/NotificationDetails/index.ts +1 -0
- package/src/{NotificationLayer/NotificationLayer.tsx → NotificationsLayer/NotificationsLayer.tsx} +9 -4
- package/src/NotificationsLayer/index.tsx +1 -0
- package/src/Overlay/Overlay.tsx +1 -6
- package/src/OverlayContent/OverlayContent.tsx +87 -0
- package/src/OverlayContent/index.ts +1 -0
- package/src/OverlayDetails/OverlayDetails.tsx +47 -0
- package/src/OverlayDetails/index.ts +1 -0
- package/src/OverlayDetailsFooter/OverlayDetailsFooter.tsx +51 -0
- package/src/OverlayDetailsFooter/index.tsx +1 -0
- package/src/OverlayDetailsHeader/OverlayDetailsHeader.tsx +35 -0
- package/src/OverlayDetailsHeader/index.ts +1 -0
- package/src/OverlayFooter/OverlayFooter.tsx +41 -0
- package/src/OverlayFooter/index.tsx +1 -0
- package/src/OverlayHeader/OverlayHeader.tsx +44 -0
- package/src/OverlayHeader/index.tsx +1 -0
- package/src/PermalinkInput/PermalinkInput.tsx +28 -0
- package/src/PermalinkInput/index.tsx +1 -0
- package/src/RouteSchedule/RouteSchedule.tsx +22 -18
- package/src/RvfFeatureDetails/RvfFeatureDetails.tsx +22 -50
- package/src/RvfFeatureDetails/RvfLineNetworkDetails/RvfLineNetworkDetails.tsx +108 -104
- package/src/RvfFeatureDetails/RvfNotificationDetails/RvfNotificationDetails.tsx +189 -154
- package/src/RvfFeatureDetails/RvfSharedMobilityDetail/RvfSharedMobilityDetails.tsx +12 -14
- package/src/RvfFeatureDetailsTitle/RvfFeatureDetailsTitle.tsx +5 -5
- package/src/RvfMainLinkButton/RvfMainLinkButton.tsx +62 -0
- package/src/RvfMainLinkButton/index.tsx +1 -0
- package/src/RvfMobilityMap/RvfMobilityMap.tsx +182 -394
- package/src/RvfOverlayContent/RvfOverlayContent.tsx +2 -2
- package/src/RvfPoisLayer/RvfPoisLayer.tsx +2 -2
- package/src/RvfSearch/RvfSearch.tsx +1 -1
- package/src/RvfSellingPointsLayer/RvfSellingPointsLayer.tsx +2 -2
- package/src/RvfSharedMobilityLayerGroup/RvfSharedMobilityLayerGroup.tsx +23 -23
- package/src/RvfTarifZonenLayer/RvfTarifZonenLayer.tsx +2 -2
- package/src/Search/Search.tsx +11 -2
- package/src/{RvfSearchButton/RvfSearchButton.tsx → SearchButton/SearchButton.tsx} +5 -5
- package/src/SearchButton/index.tsx +1 -0
- package/src/ShadowOverflow/ShadowOverflow.tsx +20 -0
- package/src/ShadowOverflow/index.tsx +1 -0
- package/src/{RvfShare/RvfPermalinkButton/RvfPermalinkButton.tsx → ShareMenu/PermalinkButton/PermalinkButton.tsx} +4 -4
- package/src/ShareMenu/PermalinkButton/index.tsx +1 -0
- package/src/{RvfShare/RvfShare.tsx → ShareMenu/ShareMenu.tsx} +9 -11
- package/src/ShareMenu/index.tsx +1 -0
- package/src/{RvfShareMenuButton/RvfShareMenuButton.tsx → ShareMenuButton/ShareMenuButton.tsx} +6 -6
- package/src/ShareMenuButton/index.tsx +1 -0
- package/src/SingleClickListener/SingleClickListener.tsx +55 -113
- package/src/SingleClickListener/index.tsx +1 -1
- package/src/Station/Station.tsx +10 -3
- package/src/StationsLayer/StationsLayer.tsx +0 -1
- package/src/StopsSearch/StopsSearch.tsx +3 -4
- package/src/StopsSearch/index.tsx +2 -1
- package/src/WindowMessageListener/WindowMessageListener.tsx +7 -1
- package/src/{RvfZoomButtons/RvfZoomButtons.tsx → ZoomButtons/ZoomButtons.tsx} +9 -12
- package/src/ZoomButtons/index.tsx +1 -0
- package/src/icons/Geolocation/airport-14-svgrepo-com.svg +41 -0
- package/src/ui/Button/Button.tsx +9 -2
- package/src/ui/Checkbox/Checkbox.tsx +32 -0
- package/src/ui/Checkbox/index.tsx +1 -0
- package/src/ui/IconButton/IconButton.tsx +24 -4
- package/src/ui/Input/Input.tsx +17 -0
- package/src/ui/Input/index.tsx +1 -0
- package/src/ui/InputCopy/InputCopy.tsx +86 -0
- package/src/ui/InputCopy/index.tsx +1 -0
- package/src/ui/Select/Select.tsx +24 -0
- package/src/ui/Select/index.tsx +1 -0
- package/src/utils/constants.ts +43 -42
- package/src/utils/hooks/useInitialLayersVisiblity.tsx +1 -1
- package/src/utils/hooks/useLayerConfig.tsx +2 -2
- package/src/utils/hooks/useLayersConfig.tsx +3 -3
- package/src/utils/hooks/useMapContext.tsx +67 -8
- package/src/utils/hooks/useRvfContext.tsx +0 -44
- package/src/NotificationLayer/index.tsx +0 -1
- package/src/RvfEmbedNavigation/DragPanWarning.ts +0 -124
- package/src/RvfEmbedNavigation/RvfEmbedNavigation.tsx +0 -51
- package/src/RvfEmbedNavigation/index.js +0 -1
- package/src/RvfExportMenu/index.tsx +0 -1
- package/src/RvfExportMenuButton/index.tsx +0 -1
- package/src/RvfFloatingMenu/RvfFloatingMenu.tsx +0 -44
- package/src/RvfFloatingMenu/index.tsx +0 -1
- package/src/RvfLayerTreeButton/index.tsx +0 -1
- package/src/RvfLineNetworkPlanLayer/index.tsx +0 -1
- package/src/RvfPermalink/RvfPermalink.tsx +0 -18
- package/src/RvfPermalink/index.tsx +0 -1
- package/src/RvfSearchButton/index.tsx +0 -1
- package/src/RvfShare/RvfPermalinkButton/index.tsx +0 -1
- package/src/RvfShare/index.tsx +0 -1
- package/src/RvfShareMenuButton/index.tsx +0 -1
- package/src/RvfTopics/index.tsx +0 -1
- package/src/RvfZoomButtons/index.tsx +0 -1
|
@@ -10,7 +10,7 @@ import RvfShare from "../RvfShare";
|
|
|
10
10
|
import RvfTopics from "../RvfTopics";
|
|
11
11
|
import Search from "../Search";
|
|
12
12
|
import Station from "../Station";
|
|
13
|
-
import {
|
|
13
|
+
import { LAYERS_TITLES } from "../utils/constants";
|
|
14
14
|
import useMapContext from "../utils/hooks/useMapContext";
|
|
15
15
|
import useRvfContext from "../utils/hooks/useRvfContext";
|
|
16
16
|
|
|
@@ -52,7 +52,7 @@ function RvfOverlayContent({
|
|
|
52
52
|
onClose={() => {
|
|
53
53
|
setTrainId(null);
|
|
54
54
|
}}
|
|
55
|
-
title={
|
|
55
|
+
title={LAYERS_TITLES.echtzeit}
|
|
56
56
|
></RvfOverlayHeader>
|
|
57
57
|
<RouteSchedule className={contentClassName} />
|
|
58
58
|
</>
|
|
@@ -2,7 +2,7 @@ import { MaplibreStyleLayer } from "mobility-toolbox-js/ol";
|
|
|
2
2
|
import { memo } from "preact/compat";
|
|
3
3
|
import { useEffect, useMemo } from "preact/hooks";
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { LAYERS_NAMES } from "../utils/constants";
|
|
6
6
|
import useMapContext from "../utils/hooks/useMapContext";
|
|
7
7
|
import useRvfContext from "../utils/hooks/useRvfContext";
|
|
8
8
|
|
|
@@ -21,7 +21,7 @@ function RvfPoisLayer(props: MaplibreStyleLayerOptions) {
|
|
|
21
21
|
return metadata?.["mapset.filter"] === "mapset_poi";
|
|
22
22
|
},
|
|
23
23
|
maplibreLayer: baseLayer,
|
|
24
|
-
name:
|
|
24
|
+
name: LAYERS_NAMES.pois,
|
|
25
25
|
visible: false,
|
|
26
26
|
...(props || {}),
|
|
27
27
|
});
|
|
@@ -8,7 +8,7 @@ import useMapContext from "../utils/hooks/useMapContext";
|
|
|
8
8
|
|
|
9
9
|
import type { StopsSearchProps } from "../StopsSearch/StopsSearch";
|
|
10
10
|
|
|
11
|
-
function RvfSearch(props: StopsSearchProps) {
|
|
11
|
+
function RvfSearch(props: Partial<StopsSearchProps>) {
|
|
12
12
|
const { apikey, map, stopsurl } = useMapContext();
|
|
13
13
|
|
|
14
14
|
const onSelect = useCallback(
|
|
@@ -5,7 +5,7 @@ import { useEffect, useMemo } from "preact/hooks";
|
|
|
5
5
|
import Automat from "../icons/Automat";
|
|
6
6
|
import InPerson from "../icons/InPerson";
|
|
7
7
|
import Video from "../icons/Video";
|
|
8
|
-
import {
|
|
8
|
+
import { LAYERS_NAMES } from "../utils/constants";
|
|
9
9
|
import useMapContext from "../utils/hooks/useMapContext";
|
|
10
10
|
import useRvfContext from "../utils/hooks/useRvfContext";
|
|
11
11
|
|
|
@@ -26,7 +26,7 @@ function RvfSellingPointsLayer(props: MaplibreStyleLayerOptions) {
|
|
|
26
26
|
return metadata?.["general.filter"] === "selling_points";
|
|
27
27
|
},
|
|
28
28
|
maplibreLayer: baseLayer,
|
|
29
|
-
name:
|
|
29
|
+
name: LAYERS_NAMES.verkaufsstellen,
|
|
30
30
|
...(props || {}),
|
|
31
31
|
|
|
32
32
|
title: (
|
|
@@ -15,8 +15,8 @@ import {
|
|
|
15
15
|
CAR_FORM_FACTOR,
|
|
16
16
|
CARGOBIKE_FORM_FACTOR,
|
|
17
17
|
LAYER_PROP_IS_EXPORTING,
|
|
18
|
+
LAYERS_NAMES,
|
|
18
19
|
RVF_EXTENT_4326,
|
|
19
|
-
RVF_LAYERS_NAMES,
|
|
20
20
|
SCOOTER_FORM_FACTOR,
|
|
21
21
|
SOURCE_FREE_FLOAT_BIKE,
|
|
22
22
|
SOURCE_FREE_FLOAT_CAR,
|
|
@@ -180,7 +180,7 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
|
|
|
180
180
|
}, [map, updateData, mbMap]);
|
|
181
181
|
|
|
182
182
|
useEffect(() => {
|
|
183
|
-
if (!mbMap || !stationsData) {
|
|
183
|
+
if (!mbMap?.style || !stationsData) {
|
|
184
184
|
return;
|
|
185
185
|
}
|
|
186
186
|
const source = mbMap.getSource(SOURCE_SHARING_STATIONS);
|
|
@@ -188,7 +188,7 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
|
|
|
188
188
|
}, [stationsData, mbMap]);
|
|
189
189
|
|
|
190
190
|
useEffect(() => {
|
|
191
|
-
if (!mbMap || !bikeFreeFloatData) {
|
|
191
|
+
if (!mbMap?.style || !bikeFreeFloatData) {
|
|
192
192
|
return;
|
|
193
193
|
}
|
|
194
194
|
const source = mbMap.getSource(SOURCE_FREE_FLOAT_BIKE);
|
|
@@ -196,7 +196,7 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
|
|
|
196
196
|
}, [mbMap, bikeFreeFloatData]);
|
|
197
197
|
|
|
198
198
|
useEffect(() => {
|
|
199
|
-
if (!mbMap || !cargoBikeFreeFloatData) {
|
|
199
|
+
if (!mbMap?.style || !cargoBikeFreeFloatData) {
|
|
200
200
|
return;
|
|
201
201
|
}
|
|
202
202
|
const source = mbMap.getSource(SOURCE_FREE_FLOAT_CARGO_BIKE);
|
|
@@ -204,7 +204,7 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
|
|
|
204
204
|
}, [mbMap, cargoBikeFreeFloatData]);
|
|
205
205
|
|
|
206
206
|
useEffect(() => {
|
|
207
|
-
if (!mbMap || !carFreeFloatData) {
|
|
207
|
+
if (!mbMap?.style || !carFreeFloatData) {
|
|
208
208
|
return;
|
|
209
209
|
}
|
|
210
210
|
const source = mbMap.getSource(SOURCE_FREE_FLOAT_CAR);
|
|
@@ -212,7 +212,7 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
|
|
|
212
212
|
}, [mbMap, carFreeFloatData]);
|
|
213
213
|
|
|
214
214
|
useEffect(() => {
|
|
215
|
-
if (!mbMap || !scooterFreeFloatData) {
|
|
215
|
+
if (!mbMap?.style || !scooterFreeFloatData) {
|
|
216
216
|
return;
|
|
217
217
|
}
|
|
218
218
|
const source = mbMap.getSource(SOURCE_FREE_FLOAT_SCOOTER);
|
|
@@ -235,7 +235,7 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
|
|
|
235
235
|
|
|
236
236
|
const bikeFrelo = new MaplibreStyleLayer({
|
|
237
237
|
maplibreLayer: baseLayer,
|
|
238
|
-
name:
|
|
238
|
+
name: LAYERS_NAMES.bikeFrelo,
|
|
239
239
|
styleLayersFilter: ({ metadata }) => {
|
|
240
240
|
return metadata?.["rvf.filter"] === "bike.frelo";
|
|
241
241
|
},
|
|
@@ -251,13 +251,13 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
|
|
|
251
251
|
|
|
252
252
|
const bikeOthers = new MaplibreStyleLayer({
|
|
253
253
|
maplibreLayer: baseLayer,
|
|
254
|
-
name:
|
|
254
|
+
name: LAYERS_NAMES.bikeOthers,
|
|
255
255
|
styleLayersFilter: ({ metadata }) => {
|
|
256
256
|
return metadata?.["rvf.filter"] === "bike.other";
|
|
257
257
|
},
|
|
258
258
|
title: (
|
|
259
259
|
<div className="flex items-center justify-between gap-2">
|
|
260
|
-
{layersConfig[
|
|
260
|
+
{layersConfig[LAYERS_NAMES.bikeOthers]?.title}
|
|
261
261
|
<Bicycle />
|
|
262
262
|
</div>
|
|
263
263
|
),
|
|
@@ -269,10 +269,10 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
|
|
|
269
269
|
return metadata?.["rvf.filter"] === "cargo_bike.frelo";
|
|
270
270
|
},
|
|
271
271
|
maplibreLayer: baseLayer,
|
|
272
|
-
name:
|
|
272
|
+
name: LAYERS_NAMES.cargobikeFrelo,
|
|
273
273
|
title: (
|
|
274
274
|
<div className="flex items-center justify-between gap-2">
|
|
275
|
-
{layersConfig[
|
|
275
|
+
{layersConfig[LAYERS_NAMES.cargobikeFrelo]?.title}
|
|
276
276
|
<CargoBike />
|
|
277
277
|
</div>
|
|
278
278
|
),
|
|
@@ -284,10 +284,10 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
|
|
|
284
284
|
return metadata?.["rvf.filter"] === "cargo_bike.other";
|
|
285
285
|
},
|
|
286
286
|
maplibreLayer: baseLayer,
|
|
287
|
-
name:
|
|
287
|
+
name: LAYERS_NAMES.cargobikeOthers,
|
|
288
288
|
title: (
|
|
289
289
|
<div className="flex items-center justify-between gap-2">
|
|
290
|
-
{layersConfig[
|
|
290
|
+
{layersConfig[LAYERS_NAMES.cargobikeOthers]?.title}
|
|
291
291
|
<CargoBike />
|
|
292
292
|
</div>
|
|
293
293
|
),
|
|
@@ -299,10 +299,10 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
|
|
|
299
299
|
return metadata?.["rvf.filter"] === "car.grueneflotte";
|
|
300
300
|
},
|
|
301
301
|
maplibreLayer: baseLayer,
|
|
302
|
-
name:
|
|
302
|
+
name: LAYERS_NAMES.carGrf,
|
|
303
303
|
title: (
|
|
304
304
|
<div className="flex items-center justify-between gap-2">
|
|
305
|
-
{layersConfig[
|
|
305
|
+
{layersConfig[LAYERS_NAMES.carGrf]?.title}
|
|
306
306
|
<Car />
|
|
307
307
|
</div>
|
|
308
308
|
),
|
|
@@ -314,10 +314,10 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
|
|
|
314
314
|
return metadata?.["rvf.filter"] === "car.naturenergy";
|
|
315
315
|
},
|
|
316
316
|
maplibreLayer: baseLayer,
|
|
317
|
-
name:
|
|
317
|
+
name: LAYERS_NAMES.carNatur,
|
|
318
318
|
title: (
|
|
319
319
|
<div className="flex items-center justify-between gap-2">
|
|
320
|
-
{layersConfig[
|
|
320
|
+
{layersConfig[LAYERS_NAMES.carNatur]?.title}
|
|
321
321
|
<Car />
|
|
322
322
|
</div>
|
|
323
323
|
),
|
|
@@ -329,10 +329,10 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
|
|
|
329
329
|
return metadata?.["rvf.filter"] === "car.other";
|
|
330
330
|
},
|
|
331
331
|
maplibreLayer: baseLayer,
|
|
332
|
-
name:
|
|
332
|
+
name: LAYERS_NAMES.carOthers,
|
|
333
333
|
title: (
|
|
334
334
|
<div className="flex items-center justify-between gap-2">
|
|
335
|
-
{layersConfig[
|
|
335
|
+
{layersConfig[LAYERS_NAMES.carOthers]?.title}
|
|
336
336
|
<Car />
|
|
337
337
|
</div>
|
|
338
338
|
),
|
|
@@ -344,10 +344,10 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
|
|
|
344
344
|
return metadata?.["rvf.filter"] === "scooter";
|
|
345
345
|
},
|
|
346
346
|
maplibreLayer: baseLayer,
|
|
347
|
-
name:
|
|
347
|
+
name: LAYERS_NAMES.eroller,
|
|
348
348
|
title: (
|
|
349
349
|
<div className="flex items-center justify-between gap-2">
|
|
350
|
-
{layersConfig[
|
|
350
|
+
{layersConfig[LAYERS_NAMES.eroller]?.title}
|
|
351
351
|
<Scooter />
|
|
352
352
|
</div>
|
|
353
353
|
),
|
|
@@ -359,10 +359,10 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
|
|
|
359
359
|
return metadata?.["rvf.filter"] === "hitchhiking";
|
|
360
360
|
},
|
|
361
361
|
maplibreLayer: baseLayer,
|
|
362
|
-
name:
|
|
362
|
+
name: LAYERS_NAMES.mitfahrpunkte,
|
|
363
363
|
title: (
|
|
364
364
|
<div className="flex items-center justify-between gap-2">
|
|
365
|
-
{layersConfig[
|
|
365
|
+
{layersConfig[LAYERS_NAMES.mitfahrpunkte]?.title}
|
|
366
366
|
<Ride />
|
|
367
367
|
</div>
|
|
368
368
|
),
|
|
@@ -2,7 +2,7 @@ import { MaplibreStyleLayer } from "mobility-toolbox-js/ol";
|
|
|
2
2
|
import { memo } from "preact/compat";
|
|
3
3
|
import { useEffect, useMemo } from "preact/hooks";
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { LAYERS_NAMES } from "../utils/constants";
|
|
6
6
|
import useMapContext from "../utils/hooks/useMapContext";
|
|
7
7
|
import useRvfContext from "../utils/hooks/useRvfContext";
|
|
8
8
|
|
|
@@ -22,7 +22,7 @@ function RvfTarifZonenLayer(props: MaplibreStyleLayerOptions) {
|
|
|
22
22
|
return metadata?.["rvf.filter"] === "zones";
|
|
23
23
|
},
|
|
24
24
|
maplibreLayer: baseLayer,
|
|
25
|
-
name:
|
|
25
|
+
name: LAYERS_NAMES.tarifzonen,
|
|
26
26
|
...(props || {}),
|
|
27
27
|
});
|
|
28
28
|
}, [baseLayer, props]);
|
package/src/Search/Search.tsx
CHANGED
|
@@ -5,7 +5,9 @@ import StopsSearch from "../StopsSearch";
|
|
|
5
5
|
import centerOnStation from "../utils/centerOnStation";
|
|
6
6
|
import useMapContext from "../utils/hooks/useMapContext";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
import type { StopsSearchProps } from "../StopsSearch/StopsSearch";
|
|
9
|
+
|
|
10
|
+
function Search(props: StopsSearchProps) {
|
|
9
11
|
const { apikey, map, stopsurl } = useMapContext();
|
|
10
12
|
|
|
11
13
|
const onSelect = useCallback(
|
|
@@ -15,6 +17,13 @@ function Search() {
|
|
|
15
17
|
[map],
|
|
16
18
|
);
|
|
17
19
|
|
|
18
|
-
return
|
|
20
|
+
return (
|
|
21
|
+
<StopsSearch
|
|
22
|
+
apikey={apikey}
|
|
23
|
+
onselect={onSelect}
|
|
24
|
+
url={stopsurl}
|
|
25
|
+
{...props}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
19
28
|
}
|
|
20
29
|
export default memo(Search);
|
|
@@ -3,15 +3,15 @@ import { useCallback } from "preact/hooks";
|
|
|
3
3
|
|
|
4
4
|
import Search from "../icons/Search";
|
|
5
5
|
import IconButton from "../ui/IconButton";
|
|
6
|
-
import
|
|
6
|
+
import useMapContext from "../utils/hooks/useMapContext";
|
|
7
7
|
|
|
8
8
|
import type { HTMLAttributes, PreactDOMAttributes } from "preact";
|
|
9
9
|
|
|
10
|
-
export type
|
|
10
|
+
export type SearchButtonProps = HTMLAttributes<HTMLButtonElement> &
|
|
11
11
|
PreactDOMAttributes;
|
|
12
12
|
|
|
13
|
-
function
|
|
14
|
-
const { isSearchOpen, setIsSearchOpen } =
|
|
13
|
+
function SearchButton({ ...props }: SearchButtonProps) {
|
|
14
|
+
const { isSearchOpen, setIsSearchOpen } = useMapContext();
|
|
15
15
|
|
|
16
16
|
const onClick = useCallback(() => {
|
|
17
17
|
setIsSearchOpen(!isSearchOpen);
|
|
@@ -24,4 +24,4 @@ function RvfSearchButton({ ...props }: RvfLayerTreeButtonProps) {
|
|
|
24
24
|
);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export default memo(
|
|
27
|
+
export default memo(SearchButton);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./SearchButton";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { memo } from "preact/compat";
|
|
2
|
+
import { twMerge } from "tailwind-merge";
|
|
3
|
+
|
|
4
|
+
import type { PreactDOMAttributes } from "preact";
|
|
5
|
+
|
|
6
|
+
function ShadowOverflow({
|
|
7
|
+
children,
|
|
8
|
+
className,
|
|
9
|
+
...props
|
|
10
|
+
}: { className?: string } & PreactDOMAttributes) {
|
|
11
|
+
return (
|
|
12
|
+
<div {...props} className={twMerge("relative overflow-y-auto", className)}>
|
|
13
|
+
<div className="pointer-events-none sticky top-0 right-0 left-0 h-4 bg-gradient-to-t from-transparent to-white"></div>
|
|
14
|
+
{children}
|
|
15
|
+
<div className="pointer-events-none sticky right-0 bottom-[-1px] left-0 h-4 bg-gradient-to-b from-transparent to-white"></div>
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default memo(ShadowOverflow);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./ShadowOverflow";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { useState } from "preact/hooks";
|
|
2
2
|
|
|
3
3
|
import Cancel from "../../icons/Cancel";
|
|
4
|
-
import
|
|
4
|
+
import ShareMenu from "../../icons/ShareMenu";
|
|
5
5
|
import RvfInputCopy from "../../RvfInputCopy";
|
|
6
6
|
import IconButton from "../../ui/IconButton";
|
|
7
7
|
|
|
8
8
|
import type { ButtonHTMLAttributes, PreactDOMAttributes } from "preact";
|
|
9
9
|
|
|
10
|
-
function
|
|
10
|
+
function PermalinkButton({
|
|
11
11
|
className,
|
|
12
12
|
...props
|
|
13
13
|
}: { className?: string } & ButtonHTMLAttributes<HTMLButtonElement> &
|
|
@@ -28,7 +28,7 @@ function RvfPermalinkButton({
|
|
|
28
28
|
selected={showTooltip}
|
|
29
29
|
{...props}
|
|
30
30
|
>
|
|
31
|
-
<
|
|
31
|
+
<ShareMenu />
|
|
32
32
|
</IconButton>
|
|
33
33
|
|
|
34
34
|
{showTooltip && positionTooltip && (
|
|
@@ -59,4 +59,4 @@ function RvfPermalinkButton({
|
|
|
59
59
|
);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
export default
|
|
62
|
+
export default PermalinkButton;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./PermalinkButton";
|
|
@@ -3,13 +3,13 @@ import { twMerge } from "tailwind-merge";
|
|
|
3
3
|
|
|
4
4
|
import Email from "../icons/Email";
|
|
5
5
|
import Image from "../icons/Image";
|
|
6
|
-
import
|
|
6
|
+
import PermalinkInput from "../PermalinkInput";
|
|
7
7
|
import Button from "../ui/Button";
|
|
8
8
|
import useMapContext from "../utils/hooks/useMapContext";
|
|
9
9
|
|
|
10
10
|
import type { HTMLAttributes, PreactDOMAttributes } from "preact";
|
|
11
11
|
|
|
12
|
-
function
|
|
12
|
+
function ShareMenu({
|
|
13
13
|
className = "",
|
|
14
14
|
...props
|
|
15
15
|
}: HTMLAttributes<HTMLDivElement> & PreactDOMAttributes) {
|
|
@@ -18,24 +18,22 @@ function RvfShare({
|
|
|
18
18
|
return (
|
|
19
19
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string, @typescript-eslint/restrict-template-expressions
|
|
20
20
|
<div className={twMerge(`flex flex-col gap-4 ${className}`)} {...props}>
|
|
21
|
-
<
|
|
22
|
-
className="
|
|
21
|
+
<Button
|
|
22
|
+
className="w-fit"
|
|
23
23
|
href={`mailto:?subject=Karte&body=${window?.location.href}`}
|
|
24
24
|
>
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
</Button>
|
|
29
|
-
</a>
|
|
25
|
+
<Email />
|
|
26
|
+
<span>Email senden</span>
|
|
27
|
+
</Button>
|
|
30
28
|
<CanvasSaveButton map={map}>
|
|
31
29
|
<Button className={"w-fit"}>
|
|
32
30
|
<Image />
|
|
33
31
|
<span>Bild speichern</span>
|
|
34
32
|
</Button>
|
|
35
33
|
</CanvasSaveButton>
|
|
36
|
-
<
|
|
34
|
+
<PermalinkInput />
|
|
37
35
|
</div>
|
|
38
36
|
);
|
|
39
37
|
}
|
|
40
38
|
|
|
41
|
-
export default
|
|
39
|
+
export default ShareMenu;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./ShareMenu";
|
package/src/{RvfShareMenuButton/RvfShareMenuButton.tsx → ShareMenuButton/ShareMenuButton.tsx}
RENAMED
|
@@ -3,15 +3,15 @@ import { useCallback } from "preact/hooks";
|
|
|
3
3
|
|
|
4
4
|
import Share from "../icons/Share";
|
|
5
5
|
import IconButton from "../ui/IconButton";
|
|
6
|
-
import
|
|
6
|
+
import useMapContext from "../utils/hooks/useMapContext";
|
|
7
7
|
|
|
8
|
-
import type {
|
|
8
|
+
import type { HTMLAttributes, PreactDOMAttributes } from "preact";
|
|
9
9
|
|
|
10
|
-
export type RvfShareMenuButtonProps =
|
|
10
|
+
export type RvfShareMenuButtonProps = HTMLAttributes<HTMLButtonElement> &
|
|
11
11
|
PreactDOMAttributes;
|
|
12
12
|
|
|
13
|
-
function
|
|
14
|
-
const { isShareMenuOpen, setIsShareMenuOpen } =
|
|
13
|
+
function ShareMenuButton({ ...props }: RvfShareMenuButtonProps) {
|
|
14
|
+
const { isShareMenuOpen, setIsShareMenuOpen } = useMapContext();
|
|
15
15
|
|
|
16
16
|
const onClick = useCallback(() => {
|
|
17
17
|
setIsShareMenuOpen(!isShareMenuOpen);
|
|
@@ -24,4 +24,4 @@ function RvfShareMenuButton({ ...props }: RvfShareMenuButtonProps) {
|
|
|
24
24
|
);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export default memo(
|
|
27
|
+
export default memo(ShareMenuButton);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./ShareMenuButton";
|
|
@@ -1,130 +1,65 @@
|
|
|
1
|
+
import debounce from "lodash.debounce";
|
|
2
|
+
import { getFeatureInfoAtCoordinate } from "mobility-toolbox-js/ol";
|
|
1
3
|
import { unByKey } from "ol/Observable";
|
|
2
4
|
import { useCallback, useEffect } from "preact/hooks";
|
|
3
5
|
|
|
4
6
|
import useMapContext from "../utils/hooks/useMapContext";
|
|
5
7
|
|
|
6
|
-
import type {
|
|
8
|
+
import type { DebounceSettings } from "lodash";
|
|
9
|
+
import type { MapBrowserEvent } from "ol";
|
|
10
|
+
import type { EventsKey } from "ol/events";
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
setSelectedFeature,
|
|
14
|
-
setSelectedFeatures,
|
|
15
|
-
setStationId,
|
|
16
|
-
setTrainId,
|
|
17
|
-
stationId,
|
|
18
|
-
stationsLayer,
|
|
19
|
-
tenant,
|
|
20
|
-
trainId,
|
|
21
|
-
} = useMapContext();
|
|
22
|
-
|
|
23
|
-
const onPointerMove = useCallback(
|
|
24
|
-
(evt: MapBrowserEvent<PointerEvent>) => {
|
|
25
|
-
const [realtimeFeature] = evt.map.getFeaturesAtPixel(evt.pixel, {
|
|
26
|
-
hitTolerance: 5,
|
|
27
|
-
layerFilter: (l) => {
|
|
28
|
-
return l === realtimeLayer;
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
realtimeLayer?.highlight(realtimeFeature as Feature);
|
|
12
|
+
export interface SingleClickListenerProps {
|
|
13
|
+
debounceOptions?: DebounceSettings;
|
|
14
|
+
debounceTimeout?: number;
|
|
15
|
+
hover?: boolean;
|
|
16
|
+
}
|
|
32
17
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
18
|
+
function SingleClickListener({
|
|
19
|
+
debounceOptions,
|
|
20
|
+
debounceTimeout = 0,
|
|
21
|
+
hover = true,
|
|
22
|
+
}: SingleClickListenerProps) {
|
|
23
|
+
const { map, queryablelayers, setFeaturesInfos, setFeaturesInfosHovered } =
|
|
24
|
+
useMapContext();
|
|
25
|
+
|
|
26
|
+
const getFeaturesInfosAtEvt = useCallback(
|
|
27
|
+
async (evt: MapBrowserEvent<PointerEvent>) => {
|
|
28
|
+
const queryableLayers = evt.map.getAllLayers().filter((l) => {
|
|
29
|
+
return queryablelayers.split(",").includes(l.get("name"));
|
|
37
30
|
});
|
|
31
|
+
const featuresInfos = await getFeatureInfoAtCoordinate(
|
|
32
|
+
evt.coordinate,
|
|
33
|
+
queryableLayers,
|
|
34
|
+
5,
|
|
35
|
+
true,
|
|
36
|
+
);
|
|
37
|
+
return featuresInfos;
|
|
38
|
+
},
|
|
39
|
+
[queryablelayers],
|
|
40
|
+
);
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
const onPointerMove = useCallback(
|
|
43
|
+
async (evt: MapBrowserEvent<PointerEvent>) => {
|
|
44
|
+
const featureInfos = await getFeaturesInfosAtEvt(evt);
|
|
45
|
+
setFeaturesInfosHovered(featureInfos);
|
|
46
|
+
const features = featureInfos.flatMap((featureInfo) => {
|
|
47
|
+
return featureInfo.features;
|
|
41
48
|
});
|
|
42
49
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return l.get("isQueryable");
|
|
47
|
-
},
|
|
48
|
-
}) as Feature[];
|
|
49
|
-
|
|
50
|
-
evt.map.getTargetElement().style.cursor =
|
|
51
|
-
realtimeFeature || stationFeature || features?.length
|
|
52
|
-
? "pointer"
|
|
53
|
-
: "default";
|
|
50
|
+
evt.map.getTargetElement().style.cursor = features?.length
|
|
51
|
+
? "pointer"
|
|
52
|
+
: "default";
|
|
54
53
|
},
|
|
55
|
-
[
|
|
54
|
+
[getFeaturesInfosAtEvt, setFeaturesInfosHovered],
|
|
56
55
|
);
|
|
57
56
|
|
|
58
57
|
const onSingleClick = useCallback(
|
|
59
|
-
(evt: MapBrowserEvent<PointerEvent>) => {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// layerFilter: (l) => {
|
|
63
|
-
// return qeryableLayers
|
|
64
|
-
// ? queryablelayers.includes(l.get("name"))
|
|
65
|
-
// : true;
|
|
66
|
-
// },
|
|
67
|
-
// });
|
|
68
|
-
// console.log("featursss", featuress);
|
|
69
|
-
|
|
70
|
-
const [realtimeFeature] = evt.map.getFeaturesAtPixel(evt.pixel, {
|
|
71
|
-
hitTolerance: 5,
|
|
72
|
-
layerFilter: (l) => {
|
|
73
|
-
return l === realtimeLayer;
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
const stationsFeatures = evt.map.getFeaturesAtPixel(evt.pixel, {
|
|
78
|
-
layerFilter: (l) => {
|
|
79
|
-
return l === stationsLayer;
|
|
80
|
-
},
|
|
81
|
-
});
|
|
82
|
-
const [stationFeature] = stationsFeatures.filter((feat) => {
|
|
83
|
-
return feat.get("tralis_network")?.includes(tenant);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
const newStationId = stationFeature?.get("uid");
|
|
87
|
-
|
|
88
|
-
const newTrainId = realtimeFeature?.get("train_id");
|
|
89
|
-
|
|
90
|
-
if (newStationId && stationId !== newStationId) {
|
|
91
|
-
setStationId(newStationId);
|
|
92
|
-
setTrainId(null);
|
|
93
|
-
} else if (newTrainId && newTrainId !== trainId) {
|
|
94
|
-
setTrainId(realtimeFeature.get("train_id"));
|
|
95
|
-
setStationId(null);
|
|
96
|
-
} else {
|
|
97
|
-
setTrainId(null);
|
|
98
|
-
setStationId(null);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Send all the features under the cursor
|
|
102
|
-
const features = evt.map.getFeaturesAtPixel(evt.pixel, {
|
|
103
|
-
layerFilter: (l) => {
|
|
104
|
-
return l.get("isQueryable");
|
|
105
|
-
},
|
|
106
|
-
}) as Feature[];
|
|
107
|
-
|
|
108
|
-
if (newStationId || newTrainId || !features.length) {
|
|
109
|
-
setSelectedFeature(null);
|
|
110
|
-
setSelectedFeatures([]);
|
|
111
|
-
} else {
|
|
112
|
-
setSelectedFeatures(features);
|
|
113
|
-
setSelectedFeature(features[0]);
|
|
114
|
-
}
|
|
58
|
+
async (evt: MapBrowserEvent<PointerEvent>) => {
|
|
59
|
+
const featuresInfos = await getFeaturesInfosAtEvt(evt);
|
|
60
|
+
setFeaturesInfos(featuresInfos);
|
|
115
61
|
},
|
|
116
|
-
[
|
|
117
|
-
// queryablelayers,
|
|
118
|
-
stationId,
|
|
119
|
-
trainId,
|
|
120
|
-
realtimeLayer,
|
|
121
|
-
stationsLayer,
|
|
122
|
-
tenant,
|
|
123
|
-
setStationId,
|
|
124
|
-
setTrainId,
|
|
125
|
-
setSelectedFeature,
|
|
126
|
-
setSelectedFeatures,
|
|
127
|
-
],
|
|
62
|
+
[getFeaturesInfosAtEvt, setFeaturesInfos],
|
|
128
63
|
);
|
|
129
64
|
|
|
130
65
|
useEffect(() => {
|
|
@@ -135,11 +70,18 @@ function SingleClickListener() {
|
|
|
135
70
|
}, [map, onSingleClick]);
|
|
136
71
|
|
|
137
72
|
useEffect(() => {
|
|
138
|
-
|
|
73
|
+
let key: EventsKey;
|
|
74
|
+
if (hover) {
|
|
75
|
+
let debounced = onPointerMove;
|
|
76
|
+
if (debounceTimeout) {
|
|
77
|
+
debounced = debounce(onPointerMove, debounceTimeout, debounceOptions);
|
|
78
|
+
}
|
|
79
|
+
key = map?.on("pointermove", debounced);
|
|
80
|
+
}
|
|
139
81
|
return () => {
|
|
140
82
|
unByKey(key);
|
|
141
83
|
};
|
|
142
|
-
}, [map, onPointerMove]);
|
|
84
|
+
}, [debounceOptions, debounceTimeout, hover, map, onPointerMove]);
|
|
143
85
|
|
|
144
86
|
return null;
|
|
145
87
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from "
|
|
1
|
+
export { default } from "./SingleClickListener";
|