@geops/rvf-mobility-web-component 0.1.64 → 0.1.65
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 +25 -0
- package/docutils.js +29 -19
- package/index.html +0 -1
- package/index.js +276 -235
- package/package.json +12 -12
- package/src/BaseLayer/BaseLayer.tsx +18 -2
- package/src/Copyright/Copyright.tsx +2 -2
- package/src/Copyright/index.tsx +1 -1
- package/src/LinesNetworkPlanLayerHighlight/LinesNetworkPlanLayerHighlight.tsx +1 -0
- package/src/Map/Map.tsx +27 -1
- package/src/MapLayout/MapLayout.tsx +1 -1
- package/src/MapLayout/index.tsx +1 -1
- package/src/MobilityMap/MobilityMap.tsx +5 -11
- package/src/MobilityMap/MobilityMapAttributes.ts +8 -5
- package/src/NotificationDetails/NotificationDetails.tsx +75 -57
- package/src/Permalink/Permalink.tsx +17 -6
- package/src/PermalinkInput/PermalinkInput.tsx +4 -1
- package/src/RealtimeLayer/index.tsx +1 -1
- package/src/RvfCopyright/RvfCopyright.tsx +32 -0
- package/src/RvfCopyright/index.tsx +1 -0
- package/src/RvfInputCopy/RvfInputCopy.tsx +18 -8
- package/src/RvfMapLayout/RvfMapLayout.tsx +198 -0
- package/src/RvfMapLayout/index.tsx +1 -0
- package/src/RvfMobilityMap/RvfMobilityMap.tsx +10 -580
- package/src/RvfRealtimeLayer/RvfRealtimeLayer.tsx +64 -0
- package/src/RvfRealtimeLayer/index.tsx +1 -0
- package/src/RvfStationsLayer/RvfStationsLayer.tsx +19 -0
- package/src/RvfStationsLayer/index.tsx +1 -0
- package/src/ShareMenu/ShareMenu.tsx +3 -1
- package/src/StationsLayer/index.tsx +1 -1
- package/src/ui/InputCopy/InputCopy.tsx +21 -10
- package/src/utils/constants.ts +1 -1
- package/src/utils/getUrlFromTemplate.test.ts +23 -0
- package/src/utils/getUrlFromTemplate.ts +47 -0
- package/src/utils/hooks/useI18n.tsx +2 -4
- package/src/utils/hooks/useInitialLayersVisiblity.tsx +27 -4
- package/src/utils/hooks/useInitialPermalink.tsx +31 -21
- package/src/utils/hooks/usePermalink.tsx +25 -0
- package/src/utils/translations.ts +4 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { memo } from "preact/compat";
|
|
2
|
+
import { twMerge } from "tailwind-merge";
|
|
3
|
+
|
|
4
|
+
import Copyright from "../Copyright";
|
|
5
|
+
import EmbedNavigation from "../EmbedNavigation";
|
|
6
|
+
import ExportMenuButton from "../ExportMenuButton";
|
|
7
|
+
import GeolocationButton from "../GeolocationButton";
|
|
8
|
+
import LayerTreeButton from "../LayerTreeButton";
|
|
9
|
+
import Map from "../Map";
|
|
10
|
+
import Overlay from "../Overlay";
|
|
11
|
+
import OverlayContent from "../OverlayContent";
|
|
12
|
+
import RvfMainLinkButton from "../RvfMainLinkButton";
|
|
13
|
+
import RvfPoisLayer from "../RvfPoisLayer";
|
|
14
|
+
import RvfSelectedFeatureHighlightLayer from "../RvfSelectedFeatureHighlightLayer";
|
|
15
|
+
import RvfSellingPointsLayer from "../RvfSellingPointsLayer";
|
|
16
|
+
import RvfSharedMobilityLayerGroup from "../RvfSharedMobilityLayerGroup";
|
|
17
|
+
import RvfTarifZonenLayer from "../RvfTarifZonenLayer";
|
|
18
|
+
import ScaleLine from "../ScaleLine";
|
|
19
|
+
import Search from "../Search";
|
|
20
|
+
import SearchButton from "../SearchButton";
|
|
21
|
+
import ShareMenuButton from "../ShareMenuButton";
|
|
22
|
+
import StationsLayer from "../StationsLayer";
|
|
23
|
+
import useMapContext from "../utils/hooks/useMapContext";
|
|
24
|
+
import ZoomButtons from "../ZoomButtons";
|
|
25
|
+
|
|
26
|
+
import type { HTMLAttributes } from "preact";
|
|
27
|
+
|
|
28
|
+
const scrollableHandlerProps = {
|
|
29
|
+
style: { width: "calc(100% - 60px)" },
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const stationsLayerProps = () => {
|
|
33
|
+
return {
|
|
34
|
+
layersFilter: ({ metadata }) => {
|
|
35
|
+
return metadata?.["general.filter"] === "stations";
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
function RvfMapLayout({
|
|
41
|
+
className,
|
|
42
|
+
...props
|
|
43
|
+
}: { className?: string } & HTMLAttributes<HTMLDivElement>) {
|
|
44
|
+
const {
|
|
45
|
+
hasDetails,
|
|
46
|
+
hasGeolocation,
|
|
47
|
+
hasLayerTree,
|
|
48
|
+
hasPrint,
|
|
49
|
+
hasRealtime,
|
|
50
|
+
hasSearch,
|
|
51
|
+
hasShare,
|
|
52
|
+
hasToolbar,
|
|
53
|
+
isEmbed,
|
|
54
|
+
isOverlayOpen,
|
|
55
|
+
isSearchOpen,
|
|
56
|
+
mainlink,
|
|
57
|
+
} = useMapContext();
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<div
|
|
61
|
+
className={twMerge(
|
|
62
|
+
"relative flex size-full flex-col text-base @lg/main:flex-row-reverse",
|
|
63
|
+
className,
|
|
64
|
+
)}
|
|
65
|
+
{...props}
|
|
66
|
+
>
|
|
67
|
+
<RvfSelectedFeatureHighlightLayer />
|
|
68
|
+
<StationsLayer minZoom={10} {...stationsLayerProps} />
|
|
69
|
+
<RvfTarifZonenLayer />
|
|
70
|
+
<RvfSellingPointsLayer />
|
|
71
|
+
<RvfPoisLayer />
|
|
72
|
+
<RvfSharedMobilityLayerGroup />
|
|
73
|
+
|
|
74
|
+
<Map className="relative flex-1 overflow-visible">
|
|
75
|
+
{isEmbed && <EmbedNavigation />}
|
|
76
|
+
{mainlink && (
|
|
77
|
+
<RvfMainLinkButton className="absolute inset-x-2 bottom-8 z-10" />
|
|
78
|
+
)}
|
|
79
|
+
|
|
80
|
+
<div className="pointer-events-none absolute inset-x-2 bottom-2 z-10 flex items-end justify-between gap-2 text-[10px]">
|
|
81
|
+
<ScaleLine className="bg-slate-50/70" />
|
|
82
|
+
<Copyright className="pointer-events-auto bg-slate-50/70" />
|
|
83
|
+
</div>
|
|
84
|
+
<div className="absolute top-2 right-2 z-10 flex">
|
|
85
|
+
{hasGeolocation && <GeolocationButton title={"Geolokalisierung"} />}
|
|
86
|
+
</div>
|
|
87
|
+
<div className="absolute right-2 bottom-10 z-10 flex flex-col justify-between gap-2">
|
|
88
|
+
<ZoomButtons />
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
{!hasToolbar && hasSearch && (
|
|
92
|
+
<div
|
|
93
|
+
className={twMerge(
|
|
94
|
+
"absolute top-2 right-2 left-2 z-10 max-w-96",
|
|
95
|
+
isOverlayOpen && "@lg:left-68",
|
|
96
|
+
)}
|
|
97
|
+
>
|
|
98
|
+
<Search />
|
|
99
|
+
</div>
|
|
100
|
+
)}
|
|
101
|
+
</Map>
|
|
102
|
+
|
|
103
|
+
<div className="pointer-events-none absolute top-2 bottom-2 left-2 z-10 flex flex-col gap-2">
|
|
104
|
+
{hasToolbar && (
|
|
105
|
+
<div
|
|
106
|
+
className={
|
|
107
|
+
"pointer-events-none relative z-10 w-fit rounded-2xl bg-black/10 p-0 backdrop-blur-sm *:pointer-events-auto"
|
|
108
|
+
}
|
|
109
|
+
// className="w-fit rounded-2xl bg-black/10 p-1 backdrop-blur-sm">
|
|
110
|
+
>
|
|
111
|
+
{hasSearch && (
|
|
112
|
+
<div
|
|
113
|
+
className={twMerge(
|
|
114
|
+
"absolute top-12 left-0 w-0 p-0 opacity-0 transition-all @sm:top-0 @sm:left-[calc(100%-43px)] @md:left-[calc(100%-47px)]",
|
|
115
|
+
isSearchOpen ? "w-64 opacity-100" : "",
|
|
116
|
+
)}
|
|
117
|
+
>
|
|
118
|
+
<Search
|
|
119
|
+
className={
|
|
120
|
+
"border-grey @container m-0 h-[40px] rounded-2xl border p-2 px-4 text-base @sm/main:h-[44px] @sm/main:rounded-l-none @sm/main:rounded-r-2xl @md/main:h-[48px]"
|
|
121
|
+
}
|
|
122
|
+
inputClassName="h-6 text-base"
|
|
123
|
+
inputContainerClassName="border-none"
|
|
124
|
+
resultClassName="text-base **:hover:cursor-pointer hover:text-red-500 p-2"
|
|
125
|
+
resultsContainerClassName="@container rounded-b-2xl max-h-[200px] overflow-y-auto border border-grey border-t-0 "
|
|
126
|
+
withResultsClassName="text-base !rounded-b-none"
|
|
127
|
+
/>
|
|
128
|
+
</div>
|
|
129
|
+
)}
|
|
130
|
+
|
|
131
|
+
<div
|
|
132
|
+
className={twMerge(
|
|
133
|
+
"border-grey relative flex gap-[1px] overflow-hidden rounded-2xl border @sm/main:h-[44px] @md/main:h-[48px]",
|
|
134
|
+
"*:size-[38px] *:rounded-none *:border-none *:@sm/main:size-[42px] *:@md/main:!size-[46px]",
|
|
135
|
+
"*:first:!rounded-l-2xl",
|
|
136
|
+
"*:last:!rounded-r-2xl",
|
|
137
|
+
isSearchOpen
|
|
138
|
+
? "@sm:rounded-r-none @sm:border-r-0 @sm:*:last:!rounded-r-none @sm:*:last:border-r-0"
|
|
139
|
+
: "",
|
|
140
|
+
)}
|
|
141
|
+
>
|
|
142
|
+
{hasPrint && <ExportMenuButton />}
|
|
143
|
+
{hasShare && <ShareMenuButton />}
|
|
144
|
+
{hasLayerTree && <LayerTreeButton />}
|
|
145
|
+
{hasSearch && <SearchButton />}
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
)}
|
|
149
|
+
|
|
150
|
+
{/* Desktop (>= lg) */}
|
|
151
|
+
<div
|
|
152
|
+
className={twMerge(
|
|
153
|
+
"pointer-events-none flex w-0 flex-1 flex-col overflow-hidden rounded-2xl",
|
|
154
|
+
isOverlayOpen ? "@lg:min-w-[320px]" : "p-0",
|
|
155
|
+
)}
|
|
156
|
+
style={{ containerType: "normal" }}
|
|
157
|
+
>
|
|
158
|
+
<Overlay
|
|
159
|
+
className={
|
|
160
|
+
"border-grey @container/overlay pointer-events-auto relative hidden flex-col overflow-hidden rounded-2xl border bg-white text-base shadow-lg @lg:flex"
|
|
161
|
+
}
|
|
162
|
+
ScrollableHandlerProps={scrollableHandlerProps}
|
|
163
|
+
>
|
|
164
|
+
<OverlayContent
|
|
165
|
+
hasDetails={hasDetails}
|
|
166
|
+
hasLayerTree={hasLayerTree}
|
|
167
|
+
hasPrint={hasPrint}
|
|
168
|
+
hasRealtime={hasRealtime}
|
|
169
|
+
hasSearch={false}
|
|
170
|
+
hasShare={hasShare}
|
|
171
|
+
/>
|
|
172
|
+
</Overlay>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
|
|
176
|
+
{/* Mobile */}
|
|
177
|
+
<Overlay
|
|
178
|
+
className={
|
|
179
|
+
isOverlayOpen
|
|
180
|
+
? "absolute bottom-0 z-20 flex max-h-[70%] min-h-[75px] w-full flex-col border-t bg-white @lg:hidden"
|
|
181
|
+
: "@lg:hidden"
|
|
182
|
+
}
|
|
183
|
+
ScrollableHandlerProps={scrollableHandlerProps}
|
|
184
|
+
>
|
|
185
|
+
<OverlayContent
|
|
186
|
+
hasDetails={hasDetails}
|
|
187
|
+
hasLayerTree={hasLayerTree}
|
|
188
|
+
hasPrint={hasPrint}
|
|
189
|
+
hasRealtime={hasRealtime}
|
|
190
|
+
hasSearch={false} // The search could be in the overlay but we decide to put it in the toolbar for better UX
|
|
191
|
+
hasShare={hasShare}
|
|
192
|
+
/>
|
|
193
|
+
</Overlay>
|
|
194
|
+
</div>
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export default memo(RvfMapLayout);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./RvfMapLayout";
|