@geops/rvf-mobility-web-component 0.1.8
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/.fixpackrc +21 -0
- package/.husky/commit-msg +1 -0
- package/.husky/post-checkout +1 -0
- package/.husky/post-merge +1 -0
- package/.husky/post-rebase +1 -0
- package/.husky/pre-commit +1 -0
- package/.lintstagedrc.js +12 -0
- package/.nvmrc +1 -0
- package/.prettierrc.js +1 -0
- package/CHANGELOG.md +183 -0
- package/Logo.svg +10 -0
- package/README.md +179 -0
- package/__mocks__/dataurl.js +11 -0
- package/__mocks__/mapbox-gl.js +19 -0
- package/commitlint.config.cjs +1 -0
- package/doc/.eslintrc.json +3 -0
- package/doc/.fixpackrc +21 -0
- package/doc/.prettierrc +1 -0
- package/doc/README.md +14 -0
- package/doc/declarations.d.ts +6 -0
- package/doc/next.config.mjs +4 -0
- package/doc/package.json +43 -0
- package/doc/postcss.config.mjs +8 -0
- package/doc/public/README.md +1 -0
- package/doc/src/app/components/GeopsAPIKeyLink.tsx +6 -0
- package/doc/src/app/components/GeopsAPIsLink.tsx +6 -0
- package/doc/src/app/components/GeopsMapsAPILink.tsx +8 -0
- package/doc/src/app/components/GeopsMobility.tsx +9 -0
- package/doc/src/app/components/GeopsMobilityDoc.tsx +231 -0
- package/doc/src/app/components/GeopsMobilitySearch.tsx +10 -0
- package/doc/src/app/components/GeopsMobilitySearchDoc.tsx +129 -0
- package/doc/src/app/components/GeopsRealtimeAPILink.tsx +10 -0
- package/doc/src/app/components/GeopsStopsAPILink.tsx +8 -0
- package/doc/src/app/components/Link.tsx +9 -0
- package/doc/src/app/components/WebComponentDoc.tsx +296 -0
- package/doc/src/app/favicon.ico +0 -0
- package/doc/src/app/geops-mobility/page.tsx +6 -0
- package/doc/src/app/geops-mobility-search/page.tsx +7 -0
- package/doc/src/app/globals.css +38 -0
- package/doc/src/app/hooks/useAttrFromUrlParams.ts +21 -0
- package/doc/src/app/hooks/useIsFullScreen.ts +14 -0
- package/doc/src/app/hooks/usePublicKey.ts +21 -0
- package/doc/src/app/layout.tsx +51 -0
- package/doc/src/app/page.tsx +86 -0
- package/doc/src/geops-ui.ts +3 -0
- package/doc/tailwind.config.ts +20 -0
- package/doc/tsconfig.json +40 -0
- package/eslint.config.mjs +40 -0
- package/favicon.ico +0 -0
- package/global.d.ts +4 -0
- package/iframe.html +34 -0
- package/index.html +276 -0
- package/index.js +2162 -0
- package/input.css +34 -0
- package/jest-setup.js +4 -0
- package/jest.config.js +17 -0
- package/package.json +80 -0
- package/scripts/build.mjs +16 -0
- package/scripts/dev.mjs +26 -0
- package/search.html +144 -0
- package/src/BaseLayer/BaseLayer.tsx +36 -0
- package/src/BaseLayer/index.tsx +1 -0
- package/src/Copyright/Copyright.tsx +54 -0
- package/src/Copyright/index.css +3 -0
- package/src/Copyright/index.tsx +1 -0
- package/src/DebugDeparture/DebugDeparture.tsx +116 -0
- package/src/DebugDeparture/index.tsx +1 -0
- package/src/DebugStop/DebugStop.tsx +47 -0
- package/src/DebugStop/index.tsx +1 -0
- package/src/Departure/Departure.tsx +55 -0
- package/src/Departure/index.tsx +1 -0
- package/src/GeolocationButton/GeolocationButton.tsx +81 -0
- package/src/GeolocationButton/index.tsx +1 -0
- package/src/Map/Map.tsx +89 -0
- package/src/Map/index.tsx +1 -0
- package/src/MobilityMap/MobilityMap.tsx +259 -0
- package/src/MobilityMap/index.css +13 -0
- package/src/MobilityMap/index.tsx +1 -0
- package/src/NotificationLayer/NotificationLayer.tsx +156 -0
- package/src/NotificationLayer/index.tsx +1 -0
- package/src/NotificationLayer/notificationUtils.ts +191 -0
- package/src/Overlay/Overlay.tsx +57 -0
- package/src/Overlay/index.tsx +1 -0
- package/src/RealtimeLayer/RealtimeLayer.tsx +230 -0
- package/src/RealtimeLayer/index.tsx +1 -0
- package/src/RouteDestination/RouteDestination.test.tsx +13 -0
- package/src/RouteDestination/RouteDestination.tsx +15 -0
- package/src/RouteDestination/index.tsx +1 -0
- package/src/RouteIcon/RouteIcon.tsx +66 -0
- package/src/RouteIcon/index.tsx +1 -0
- package/src/RouteIdentifier/RouteIdentifer.tsx +35 -0
- package/src/RouteIdentifier/index.tsx +1 -0
- package/src/RouteInfos/RouteInfos.tsx +22 -0
- package/src/RouteInfos/index.tsx +1 -0
- package/src/RouteSchedule/RouteSchedule.tsx +69 -0
- package/src/RouteSchedule/firstStation.png +0 -0
- package/src/RouteSchedule/index.tsx +1 -0
- package/src/RouteSchedule/lastStation.png +0 -0
- package/src/RouteSchedule/line.png +0 -0
- package/src/RouteSchedule/station.png +0 -0
- package/src/RouteScheduleFooter/RouteScheduleFooter.tsx +44 -0
- package/src/RouteScheduleFooter/index.tsx +1 -0
- package/src/RouteScheduleHeader/RouteScheduleHeader.tsx +58 -0
- package/src/RouteScheduleHeader/index.tsx +1 -0
- package/src/RouteStop/RouteStop.tsx +121 -0
- package/src/RouteStop/index.tsx +1 -0
- package/src/RouteStopDelay/RouteStopDelay.tsx +36 -0
- package/src/RouteStopDelay/index.tsx +1 -0
- package/src/RouteStopName/RouteStopName.tsx +24 -0
- package/src/RouteStopName/index.tsx +1 -0
- package/src/RouteStopPlatform/RouteStopPlatform.tsx +29 -0
- package/src/RouteStopPlatform/index.tsx +1 -0
- package/src/RouteStopProgress/RouteStopProgress.tsx +101 -0
- package/src/RouteStopProgress/index.tsx +1 -0
- package/src/RouteStopServices/RouteStopServices.tsx +26 -0
- package/src/RouteStopServices/index.tsx +1 -0
- package/src/RouteStopStation/RouteStopStation.tsx +32 -0
- package/src/RouteStopStation/index.tsx +1 -0
- package/src/RouteStopTime/RouteStopTime.tsx +34 -0
- package/src/RouteStopTime/index.tsx +1 -0
- package/src/RvfMobilityMap/RvfMobilityMap.tsx +245 -0
- package/src/RvfMobilityMap/index.css +13 -0
- package/src/RvfMobilityMap/index.tsx +1 -0
- package/src/ScaleLine/ScaleLine.tsx +51 -0
- package/src/ScaleLine/index.css +6 -0
- package/src/ScaleLine/index.tsx +1 -0
- package/src/ScrollableHandler/ScrollableHandler.tsx +65 -0
- package/src/ScrollableHandler/index.tsx +1 -0
- package/src/Search/Search.tsx +18 -0
- package/src/Search/index.tsx +1 -0
- package/src/SingleClickListener/SingleClickListener.tsx +103 -0
- package/src/SingleClickListener/index.tsx +1 -0
- package/src/Station/Station.tsx +68 -0
- package/src/Station/index.tsx +1 -0
- package/src/StationHeader/StationHeader.tsx +32 -0
- package/src/StationHeader/index.tsx +1 -0
- package/src/StationName/StationName.tsx +21 -0
- package/src/StationName/index.tsx +1 -0
- package/src/StationServices/StationServices.tsx +80 -0
- package/src/StationServices/index.tsx +1 -0
- package/src/StationsLayer/StationsLayer.tsx +41 -0
- package/src/StationsLayer/index.tsx +1 -0
- package/src/StopsSearch/StopsSearch.tsx +254 -0
- package/src/StopsSearch/index.tsx +1 -0
- package/src/icons/Airport/Airport.tsx +17 -0
- package/src/icons/Airport/airport-14-svgrepo-com.svg +41 -0
- package/src/icons/Airport/index.tsx +1 -0
- package/src/icons/BarAndRestaurants/BarAndRestaurants.tsx +17 -0
- package/src/icons/BarAndRestaurants/food-restaurant-svgrepo-com.svg +12 -0
- package/src/icons/BarAndRestaurants/index.tsx +1 -0
- package/src/icons/Bathroom/Bathroom.tsx +59 -0
- package/src/icons/Bathroom/bathroom-restroom-svgrepo-com.svg +38 -0
- package/src/icons/Bathroom/index.tsx +1 -0
- package/src/icons/BikeStorage/BikeStorage.tsx +17 -0
- package/src/icons/BikeStorage/index.tsx +1 -0
- package/src/icons/BikeStorage/parking-bicycle-14-svgrepo-com.svg +41 -0
- package/src/icons/Elevator/Elevator.tsx +16 -0
- package/src/icons/Elevator/elevator-svgrepo-com.svg +2 -0
- package/src/icons/Elevator/index.tsx +1 -0
- package/src/icons/Police/Police.tsx +20 -0
- package/src/icons/Police/index.tsx +1 -0
- package/src/icons/Police/polizia.png +0 -0
- package/src/icons/README.md +52 -0
- package/src/icons/WaitingAreas/WaitingAreas.tsx +16 -0
- package/src/icons/WaitingAreas/highway-rest-area-svgrepo-com.svg +5 -0
- package/src/icons/WaitingAreas/index.tsx +1 -0
- package/src/icons/WaitingAreas/wheelchair-svgrepo-com.svg +2 -0
- package/src/icons/WheelChair/WheelChair.tsx +16 -0
- package/src/icons/WheelChair/disabili.png +0 -0
- package/src/icons/WheelChair/index.tsx +1 -0
- package/src/icons/WheelChair/wheelchair-svgrepo-com.svg +2 -0
- package/src/index.tsx +50 -0
- package/src/utils/MobilityEvent.ts +21 -0
- package/src/utils/addSourceAndLayers.ts +62 -0
- package/src/utils/centerOnStation.ts +17 -0
- package/src/utils/centerOnVehicle.ts +50 -0
- package/src/utils/getBgColor.ts +3 -0
- package/src/utils/getDelayColor.test.ts +20 -0
- package/src/utils/getDelayColor.ts +23 -0
- package/src/utils/getDelayColorForVehicle.test.ts +28 -0
- package/src/utils/getDelayColorForVehicle.ts +25 -0
- package/src/utils/getDelayFontForVehicle.test.ts +7 -0
- package/src/utils/getDelayFontForVehicle.tsx +8 -0
- package/src/utils/getDelayString.test.ts +22 -0
- package/src/utils/getDelayString.ts +28 -0
- package/src/utils/getDelayTextForVehicle.test.ts +28 -0
- package/src/utils/getDelayTextForVehicle.ts +21 -0
- package/src/utils/getFullTrajectoryAndFit.ts +40 -0
- package/src/utils/getHoursAndMinutes.test.ts +14 -0
- package/src/utils/getHoursAndMinutes.ts +22 -0
- package/src/utils/getMainColorForVehicle.test.ts +27 -0
- package/src/utils/getMainColorForVehicle.ts +46 -0
- package/src/utils/getStopStatus.test.ts +104 -0
- package/src/utils/getStopStatus.ts +171 -0
- package/src/utils/getTextFontForVehicle.test.ts +7 -0
- package/src/utils/getTextFontForVehicle.tsx +9 -0
- package/src/utils/getTextForVehicle.test.ts +17 -0
- package/src/utils/getTextForVehicle.ts +19 -0
- package/src/utils/hooks/useDebug.tsx +11 -0
- package/src/utils/hooks/useDeparture.tsx +23 -0
- package/src/utils/hooks/useI18n.tsx +20 -0
- package/src/utils/hooks/useMapContext.tsx +74 -0
- package/src/utils/hooks/useParams.ts +5 -0
- package/src/utils/hooks/useRouteStop.tsx +33 -0
- package/src/utils/hooks/useStation.tsx +21 -0
- package/src/utils/hooks/useUpdatePermalink.tsx +33 -0
- package/src/utils/hooks/useZoom.tsx +32 -0
- package/src/utils/i18n.ts +16 -0
- package/src/utils/translations.ts +31 -0
- package/tailwind.config.mjs +56 -0
- package/testNotification.json +50653 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line react/display-name
|
|
5
|
+
const GeopsMobility = forwardRef((props: Record<string, unknown>, ref) => {
|
|
6
|
+
return <geops-mobility ref={ref} {...props}></geops-mobility>;
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export default GeopsMobility;
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { Typography } from "@mui/material";
|
|
2
|
+
import { Suspense } from "react";
|
|
3
|
+
|
|
4
|
+
import useIsFullScreen from "../hooks/useIsFullScreen";
|
|
5
|
+
import GeopsAPIKeyLink from "./GeopsAPIKeyLink";
|
|
6
|
+
import GeopsMapsAPILink from "./GeopsMapsAPILink";
|
|
7
|
+
import GeopsMobility from "./GeopsMobility";
|
|
8
|
+
import GeopsRealtimeAPILink from "./GeopsRealtimeAPILink";
|
|
9
|
+
import GeopsStopsAPILink from "./GeopsStopsAPILink";
|
|
10
|
+
import Link from "./Link";
|
|
11
|
+
import WebComponentDoc, { AttrConfig } from "./WebComponentDoc";
|
|
12
|
+
|
|
13
|
+
const attrsConfig: Record<string, AttrConfig> = {
|
|
14
|
+
apikey: {
|
|
15
|
+
description: (
|
|
16
|
+
<Typography>
|
|
17
|
+
Your <GeopsAPIKeyLink />.
|
|
18
|
+
</Typography>
|
|
19
|
+
),
|
|
20
|
+
type: "textfield",
|
|
21
|
+
},
|
|
22
|
+
baselayer: {
|
|
23
|
+
defaultValue: "travic_v2",
|
|
24
|
+
description: (
|
|
25
|
+
<Typography>
|
|
26
|
+
The style's name from the <GeopsMapsAPILink />
|
|
27
|
+
(base_dark_v2, base_bright_v2, ...).
|
|
28
|
+
</Typography>
|
|
29
|
+
),
|
|
30
|
+
type: "select",
|
|
31
|
+
},
|
|
32
|
+
center: {
|
|
33
|
+
defaultValue: "831634,5933959",
|
|
34
|
+
description: (
|
|
35
|
+
<Typography>The center of the map in EPSG:3857 coordinates.</Typography>
|
|
36
|
+
),
|
|
37
|
+
type: "textfield",
|
|
38
|
+
},
|
|
39
|
+
geolocation: {
|
|
40
|
+
defaultValue: "true",
|
|
41
|
+
description: (
|
|
42
|
+
<Typography>
|
|
43
|
+
Display the geolocation button or not (true or false).
|
|
44
|
+
</Typography>
|
|
45
|
+
),
|
|
46
|
+
type: "checkbox",
|
|
47
|
+
},
|
|
48
|
+
mapsurl: {
|
|
49
|
+
defaultValue: "https://maps.geops.io",
|
|
50
|
+
description: (
|
|
51
|
+
<Typography>
|
|
52
|
+
The <GeopsMapsAPILink /> url to use.
|
|
53
|
+
</Typography>
|
|
54
|
+
),
|
|
55
|
+
type: "textfield",
|
|
56
|
+
},
|
|
57
|
+
maxzoom: {
|
|
58
|
+
description: <Typography>Define the max zoom level of the map.</Typography>,
|
|
59
|
+
props: {
|
|
60
|
+
slotProps: {
|
|
61
|
+
input: {
|
|
62
|
+
max: 22,
|
|
63
|
+
min: 0,
|
|
64
|
+
step: 1,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
type: "number",
|
|
68
|
+
},
|
|
69
|
+
type: "textfield",
|
|
70
|
+
},
|
|
71
|
+
minzoom: {
|
|
72
|
+
description: <Typography>Define the min zoom level of the map.</Typography>,
|
|
73
|
+
props: {
|
|
74
|
+
slotProps: {
|
|
75
|
+
input: {
|
|
76
|
+
max: 22,
|
|
77
|
+
min: 0,
|
|
78
|
+
step: 1,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
type: "number",
|
|
82
|
+
},
|
|
83
|
+
type: "textfield",
|
|
84
|
+
},
|
|
85
|
+
mots: {
|
|
86
|
+
description: (
|
|
87
|
+
<Typography>
|
|
88
|
+
Commas separated list of mots to display on the Realtime layer (rail,
|
|
89
|
+
bus, coach, foot, tram, subway, gondola, funicular, ferry, car).
|
|
90
|
+
</Typography>
|
|
91
|
+
),
|
|
92
|
+
type: "textfield",
|
|
93
|
+
},
|
|
94
|
+
notification: {
|
|
95
|
+
defaultValue: "true",
|
|
96
|
+
description: (
|
|
97
|
+
<Typography>
|
|
98
|
+
Display the notification layer or not (true or false). This layer will
|
|
99
|
+
display informations about disruptions on the network. Data comes from
|
|
100
|
+
our{" "}
|
|
101
|
+
<Link href="https://geops.com/en/solution/disruption-information">
|
|
102
|
+
geOps MOCO tool
|
|
103
|
+
</Link>
|
|
104
|
+
. It works it combination with `notificationurl`.
|
|
105
|
+
</Typography>
|
|
106
|
+
),
|
|
107
|
+
type: "checkbox",
|
|
108
|
+
},
|
|
109
|
+
notificationat: {
|
|
110
|
+
description: (
|
|
111
|
+
<Typography>
|
|
112
|
+
An ISO date string used to display active notification at this date in
|
|
113
|
+
the notification layer. If not defined the current date will be used.
|
|
114
|
+
</Typography>
|
|
115
|
+
),
|
|
116
|
+
type: "textfield",
|
|
117
|
+
},
|
|
118
|
+
notificationbeforelayerid: {
|
|
119
|
+
description: (
|
|
120
|
+
<Typography>
|
|
121
|
+
The style layer's id before which the notification layer will be
|
|
122
|
+
added. By default the layer will be added on top.
|
|
123
|
+
</Typography>
|
|
124
|
+
),
|
|
125
|
+
type: "textfield",
|
|
126
|
+
},
|
|
127
|
+
notificationurl: {
|
|
128
|
+
description: (
|
|
129
|
+
<Typography>
|
|
130
|
+
The{" "}
|
|
131
|
+
<Link href="https://geops.com/en/solution/disruption-information">
|
|
132
|
+
geOps MOCO API
|
|
133
|
+
</Link>{" "}
|
|
134
|
+
url to get the notifications from.
|
|
135
|
+
</Typography>
|
|
136
|
+
),
|
|
137
|
+
type: "textfield",
|
|
138
|
+
},
|
|
139
|
+
// x,y,z are not applies on refresh
|
|
140
|
+
// permalink: {
|
|
141
|
+
// defaultValue: "false",
|
|
142
|
+
// description: (
|
|
143
|
+
// <Typography>
|
|
144
|
+
// Add automatically an `x`,`y` an `z` URL parameters to the URL to allow
|
|
145
|
+
// to share the current mapview. Default to false.
|
|
146
|
+
// </Typography>
|
|
147
|
+
// ),
|
|
148
|
+
// type: "checkbox",
|
|
149
|
+
// },
|
|
150
|
+
realtime: {
|
|
151
|
+
defaultValue: "true",
|
|
152
|
+
description: (
|
|
153
|
+
<Typography>
|
|
154
|
+
Display the realtime layer or not (true or false). This layer display
|
|
155
|
+
realtime vehicles on the map using the <GeopsRealtimeAPILink />.
|
|
156
|
+
</Typography>
|
|
157
|
+
),
|
|
158
|
+
type: "checkbox",
|
|
159
|
+
},
|
|
160
|
+
realtimeurl: {
|
|
161
|
+
defaultValue: "wss://api.geops.io/tracker-ws/v1/ws",
|
|
162
|
+
description: (
|
|
163
|
+
<Typography>
|
|
164
|
+
The <GeopsRealtimeAPILink /> url to use.
|
|
165
|
+
</Typography>
|
|
166
|
+
),
|
|
167
|
+
type: "textfield",
|
|
168
|
+
},
|
|
169
|
+
search: {
|
|
170
|
+
defaultValue: "true",
|
|
171
|
+
description: (
|
|
172
|
+
<Typography>
|
|
173
|
+
Display the search stops input or not (true or false).
|
|
174
|
+
</Typography>
|
|
175
|
+
),
|
|
176
|
+
type: "checkbox",
|
|
177
|
+
},
|
|
178
|
+
stopsurl: {
|
|
179
|
+
defaultValue: "https://api.geops.io/stops/v1/",
|
|
180
|
+
description: (
|
|
181
|
+
<Typography>
|
|
182
|
+
The <GeopsStopsAPILink /> url to use.
|
|
183
|
+
</Typography>
|
|
184
|
+
),
|
|
185
|
+
type: "textfield",
|
|
186
|
+
},
|
|
187
|
+
tenant: {
|
|
188
|
+
description: (
|
|
189
|
+
<Typography>
|
|
190
|
+
The tenant name to use to filter the Realtime vehicles available.
|
|
191
|
+
</Typography>
|
|
192
|
+
),
|
|
193
|
+
type: "textfield",
|
|
194
|
+
},
|
|
195
|
+
zoom: {
|
|
196
|
+
defaultValue: "13",
|
|
197
|
+
description: <Typography>The initial zoom level of the map.</Typography>,
|
|
198
|
+
props: {
|
|
199
|
+
slotProps: {
|
|
200
|
+
input: {
|
|
201
|
+
max: 22,
|
|
202
|
+
min: 0,
|
|
203
|
+
step: 1,
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
type: "number",
|
|
207
|
+
},
|
|
208
|
+
type: "textfield",
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
function GeopsMobilityDoc() {
|
|
212
|
+
const isFullScreen = useIsFullScreen();
|
|
213
|
+
|
|
214
|
+
return (
|
|
215
|
+
<Suspense>
|
|
216
|
+
<WebComponentDoc
|
|
217
|
+
attrsConfig={attrsConfig}
|
|
218
|
+
// @ts-expect-error - must find the correct type
|
|
219
|
+
Comp={GeopsMobility}
|
|
220
|
+
compProps={{
|
|
221
|
+
class: isFullScreen
|
|
222
|
+
? "fixed inset-0 w-screen h-sccreen z-[9000] bg-white"
|
|
223
|
+
: "block h-96 max-w-full resize overflow-auto bg-white",
|
|
224
|
+
}}
|
|
225
|
+
tagName="geops-mobility"
|
|
226
|
+
/>
|
|
227
|
+
</Suspense>
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export default GeopsMobilityDoc;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line react/display-name
|
|
4
|
+
const GeopsMobilitySearch = forwardRef(
|
|
5
|
+
(props: Record<string, unknown>, ref) => {
|
|
6
|
+
return <geops-mobility-search ref={ref} {...props}></geops-mobility-search>;
|
|
7
|
+
},
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
export default GeopsMobilitySearch;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { Typography } from "@mui/material";
|
|
2
|
+
import { Suspense } from "react";
|
|
3
|
+
|
|
4
|
+
import GeopsAPIKeyLink from "./GeopsAPIKeyLink";
|
|
5
|
+
import GeopsMobilitySearch from "./GeopsMobilitySearch";
|
|
6
|
+
import GeopsStopsAPILink from "./GeopsStopsAPILink";
|
|
7
|
+
import WebComponentDoc, { AttrConfig } from "./WebComponentDoc";
|
|
8
|
+
|
|
9
|
+
const attrsConfig: Record<string, AttrConfig> = {
|
|
10
|
+
apikey: {
|
|
11
|
+
description: (
|
|
12
|
+
<Typography>
|
|
13
|
+
Your <GeopsAPIKeyLink />.
|
|
14
|
+
</Typography>
|
|
15
|
+
),
|
|
16
|
+
type: "textfield",
|
|
17
|
+
},
|
|
18
|
+
bbox: {
|
|
19
|
+
description: (
|
|
20
|
+
<Typography>
|
|
21
|
+
The extent where to search the stops (minx,miny,maxx,maxy).
|
|
22
|
+
</Typography>
|
|
23
|
+
),
|
|
24
|
+
type: "textfield",
|
|
25
|
+
},
|
|
26
|
+
countrycode: {
|
|
27
|
+
description: (
|
|
28
|
+
<Typography>
|
|
29
|
+
The country code to filter the results (IT, DE, CH ...)
|
|
30
|
+
</Typography>
|
|
31
|
+
),
|
|
32
|
+
type: "textfield",
|
|
33
|
+
},
|
|
34
|
+
event: {
|
|
35
|
+
defaultValue: "mwc:stopssearchselect",
|
|
36
|
+
description: (
|
|
37
|
+
<Typography>
|
|
38
|
+
The event&pos;s name to listen to when a stop is selected.
|
|
39
|
+
</Typography>
|
|
40
|
+
),
|
|
41
|
+
type: "textfield",
|
|
42
|
+
},
|
|
43
|
+
field: {
|
|
44
|
+
description: (
|
|
45
|
+
<Typography>
|
|
46
|
+
Which field to look up, default all of them, Possible values:id, name,
|
|
47
|
+
coords.
|
|
48
|
+
</Typography>
|
|
49
|
+
),
|
|
50
|
+
type: "textfield",
|
|
51
|
+
},
|
|
52
|
+
limit: {
|
|
53
|
+
defaultValue: "5",
|
|
54
|
+
description: <Typography>The number of suggestions to show.</Typography>,
|
|
55
|
+
props: {
|
|
56
|
+
slotProps: {
|
|
57
|
+
input: {
|
|
58
|
+
max: 100,
|
|
59
|
+
min: 0,
|
|
60
|
+
step: 1,
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
type: "number",
|
|
64
|
+
},
|
|
65
|
+
type: "textfield",
|
|
66
|
+
},
|
|
67
|
+
mots: {
|
|
68
|
+
description: (
|
|
69
|
+
<Typography>
|
|
70
|
+
Commas separated list of mots used to filter the results (rail, bus,
|
|
71
|
+
coach, foot, tram, subway, gondola, funicular, ferry, car).
|
|
72
|
+
</Typography>
|
|
73
|
+
),
|
|
74
|
+
type: "textfield",
|
|
75
|
+
},
|
|
76
|
+
params: {
|
|
77
|
+
description: (
|
|
78
|
+
<Typography>
|
|
79
|
+
JSON string with additional parameters to pass to the request to the
|
|
80
|
+
API. Ex: {"{ 'key': 'value' }"}
|
|
81
|
+
</Typography>
|
|
82
|
+
),
|
|
83
|
+
type: "textfield",
|
|
84
|
+
},
|
|
85
|
+
prefagencies: {
|
|
86
|
+
description: (
|
|
87
|
+
<Typography>
|
|
88
|
+
Comma seperated list, order chooses which agency will be preferred as
|
|
89
|
+
ident_source (for id and code fields). Possible values: sbb, db.
|
|
90
|
+
</Typography>
|
|
91
|
+
),
|
|
92
|
+
type: "textfield",
|
|
93
|
+
},
|
|
94
|
+
reflocation: {
|
|
95
|
+
description: (
|
|
96
|
+
<Typography>
|
|
97
|
+
Coordinates in WGS84 (in lat,lon order) used to rank stops close to this
|
|
98
|
+
position higher
|
|
99
|
+
</Typography>
|
|
100
|
+
),
|
|
101
|
+
type: "textfield",
|
|
102
|
+
},
|
|
103
|
+
url: {
|
|
104
|
+
defaultValue: "https://api.geops.io/stops/v1/",
|
|
105
|
+
description: (
|
|
106
|
+
<Typography>
|
|
107
|
+
The <GeopsStopsAPILink /> url to use.
|
|
108
|
+
</Typography>
|
|
109
|
+
),
|
|
110
|
+
type: "textfield",
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
function GeopsMobilitySearchDoc() {
|
|
115
|
+
return (
|
|
116
|
+
<Suspense>
|
|
117
|
+
<WebComponentDoc
|
|
118
|
+
attrsConfig={attrsConfig}
|
|
119
|
+
// @ts-expect-error - must find the correct type
|
|
120
|
+
Comp={GeopsMobilitySearch}
|
|
121
|
+
compProps={{ class: "block w-full border" }}
|
|
122
|
+
events={["mwc:stopssearchselect"]}
|
|
123
|
+
tagName="geops-mobility-search"
|
|
124
|
+
/>
|
|
125
|
+
</Suspense>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export default GeopsMobilitySearchDoc;
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
Checkbox,
|
|
5
|
+
MenuItem,
|
|
6
|
+
Select,
|
|
7
|
+
TextField,
|
|
8
|
+
TextFieldProps,
|
|
9
|
+
Typography,
|
|
10
|
+
} from "@mui/material";
|
|
11
|
+
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
|
12
|
+
import {
|
|
13
|
+
ReactElement,
|
|
14
|
+
ReactNode,
|
|
15
|
+
useCallback,
|
|
16
|
+
useEffect,
|
|
17
|
+
useMemo,
|
|
18
|
+
useRef,
|
|
19
|
+
} from "react";
|
|
20
|
+
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
|
21
|
+
|
|
22
|
+
import useAttrFromUrlParams from "../hooks/useAttrFromUrlParams";
|
|
23
|
+
import usePublicKey from "../hooks/usePublicKey";
|
|
24
|
+
|
|
25
|
+
export interface AttrConfig {
|
|
26
|
+
defaultValue?: string;
|
|
27
|
+
description: ReactNode;
|
|
28
|
+
props?: TextFieldProps;
|
|
29
|
+
type: "checkbox" | "date" | "select" | "textfield";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function WebComponentDoc({
|
|
33
|
+
attrsConfig,
|
|
34
|
+
Comp,
|
|
35
|
+
compProps,
|
|
36
|
+
events,
|
|
37
|
+
isFullScreen,
|
|
38
|
+
tagName,
|
|
39
|
+
}: {
|
|
40
|
+
attrsConfig: Record<string, AttrConfig>;
|
|
41
|
+
Comp: (props: Record<string, string>) => ReactElement;
|
|
42
|
+
compProps: Record<string, string>;
|
|
43
|
+
events?: string[];
|
|
44
|
+
isFullScreen?: boolean;
|
|
45
|
+
tagName: string;
|
|
46
|
+
}) {
|
|
47
|
+
const wcAttributes = Object.keys(attrsConfig);
|
|
48
|
+
const ref = useRef<HTMLElement>(null);
|
|
49
|
+
const router = useRouter();
|
|
50
|
+
const pathname = usePathname();
|
|
51
|
+
const apiKey = usePublicKey();
|
|
52
|
+
const attributes = useAttrFromUrlParams(wcAttributes);
|
|
53
|
+
const searchParams = useSearchParams();
|
|
54
|
+
|
|
55
|
+
// Get a new searchParams string by merging the current
|
|
56
|
+
// searchParams with a provided key/value pair
|
|
57
|
+
const createQueryString = useCallback(
|
|
58
|
+
(name: string, value?: string) => {
|
|
59
|
+
const params = new URLSearchParams(searchParams.toString());
|
|
60
|
+
if (value === undefined || value === "") {
|
|
61
|
+
params.delete(name);
|
|
62
|
+
} else {
|
|
63
|
+
params.set(name, value);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return params.toString();
|
|
67
|
+
},
|
|
68
|
+
[searchParams],
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const code = useMemo(() => {
|
|
72
|
+
let str = `<script\n\ttype="module"\n\tsrc="https://www.unpkg.com/@geops/mobility-web-component">
|
|
73
|
+
</script>
|
|
74
|
+
<${tagName}`;
|
|
75
|
+
|
|
76
|
+
str = Object.keys({ apikey: "", ...attributes }).reduce((acc, key) => {
|
|
77
|
+
if (key === "apikey" && !attributes[key]) {
|
|
78
|
+
return `${acc}\n\tapikey="YOUR_GEOPS_API_KEY"`;
|
|
79
|
+
}
|
|
80
|
+
return `${acc}\n\t${key}="${attributes[key]}"`;
|
|
81
|
+
}, str);
|
|
82
|
+
|
|
83
|
+
str += `>\n</${tagName}>`;
|
|
84
|
+
|
|
85
|
+
return str;
|
|
86
|
+
}, [attributes, tagName]);
|
|
87
|
+
|
|
88
|
+
const onChange = useCallback(
|
|
89
|
+
(key: string, value: string) => {
|
|
90
|
+
const val = value === attrsConfig[key]?.defaultValue ? undefined : value;
|
|
91
|
+
router.replace(pathname + "?" + createQueryString(key, val), {
|
|
92
|
+
scroll: false,
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
[attrsConfig, createQueryString, pathname, router],
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
const cb = (event: CustomEvent<{ data: object; type: string }>) => {
|
|
100
|
+
const eventLog = document.getElementById("textarea");
|
|
101
|
+
// @ts-expect-error - strange error
|
|
102
|
+
const data = event.data;
|
|
103
|
+
if (!eventLog) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (!data) {
|
|
107
|
+
eventLog.innerText = "";
|
|
108
|
+
} else {
|
|
109
|
+
eventLog.innerText =
|
|
110
|
+
"Event " +
|
|
111
|
+
event.type +
|
|
112
|
+
" received :\n " +
|
|
113
|
+
JSON.stringify(data, undefined, " ");
|
|
114
|
+
// window.top.postMessage(data, "*");
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
if (ref.current) {
|
|
118
|
+
// Listen to element event
|
|
119
|
+
events?.forEach((event) => {
|
|
120
|
+
// @ts-expect-error - strange error
|
|
121
|
+
ref.current?.addEventListener(event, cb);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return () => {
|
|
125
|
+
events?.forEach((event) => {
|
|
126
|
+
// @ts-expect-error - strange error
|
|
127
|
+
ref.current?.removeEventListener(event, cb);
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
}, [events]);
|
|
131
|
+
|
|
132
|
+
const webComponent = useMemo(() => {
|
|
133
|
+
return (
|
|
134
|
+
<Comp
|
|
135
|
+
// @ts-expect-error - strange error
|
|
136
|
+
apikey={apiKey}
|
|
137
|
+
{...attributes}
|
|
138
|
+
// @ts-expect-error - strange error
|
|
139
|
+
ref={(node: HTMLElement) => {
|
|
140
|
+
// @ts-expect-error - strange error
|
|
141
|
+
ref.current = node;
|
|
142
|
+
}}
|
|
143
|
+
{...compProps}
|
|
144
|
+
/>
|
|
145
|
+
);
|
|
146
|
+
}, [Comp, apiKey, attributes, compProps]);
|
|
147
|
+
|
|
148
|
+
if (isFullScreen) {
|
|
149
|
+
return webComponent;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<div className="mb-48 scroll-mt-20">
|
|
154
|
+
<Typography variant="h1">{`<${tagName} />`}</Typography>
|
|
155
|
+
<br />
|
|
156
|
+
<Typography>
|
|
157
|
+
This is a demo of the <{tagName} /> Web Component.
|
|
158
|
+
</Typography>
|
|
159
|
+
<br />
|
|
160
|
+
{webComponent}
|
|
161
|
+
<br />
|
|
162
|
+
{events?.length && (
|
|
163
|
+
<>
|
|
164
|
+
<Typography className="my-8 overflow-auto" variant="h3">
|
|
165
|
+
Event received
|
|
166
|
+
</Typography>
|
|
167
|
+
<pre
|
|
168
|
+
className="h-40 w-full overflow-auto border p-2"
|
|
169
|
+
id="textarea"
|
|
170
|
+
></pre>
|
|
171
|
+
<br />
|
|
172
|
+
</>
|
|
173
|
+
)}
|
|
174
|
+
<Typography className="my-8" variant="h2">
|
|
175
|
+
HTML code
|
|
176
|
+
</Typography>
|
|
177
|
+
<br />
|
|
178
|
+
<SyntaxHighlighter className="!m-0" language="xml">
|
|
179
|
+
{code}
|
|
180
|
+
</SyntaxHighlighter>
|
|
181
|
+
<br />
|
|
182
|
+
<Typography className="flex gap-4" variant="h2">
|
|
183
|
+
Attributes
|
|
184
|
+
<Button
|
|
185
|
+
onClick={() => {
|
|
186
|
+
router.push(pathname, {
|
|
187
|
+
scroll: false,
|
|
188
|
+
});
|
|
189
|
+
}}
|
|
190
|
+
>
|
|
191
|
+
Reset
|
|
192
|
+
</Button>
|
|
193
|
+
</Typography>
|
|
194
|
+
<br />
|
|
195
|
+
|
|
196
|
+
<table className="w-full">
|
|
197
|
+
<thead>
|
|
198
|
+
<tr>
|
|
199
|
+
<th className="w-[15%] border px-4 py-2">Name</th>
|
|
200
|
+
<th className="w-2/5 border px-4 py-2">Value</th>
|
|
201
|
+
<th className="w-[45%] border px-4 py-2">Description</th>
|
|
202
|
+
</tr>
|
|
203
|
+
</thead>
|
|
204
|
+
<tbody>
|
|
205
|
+
{wcAttributes
|
|
206
|
+
.sort((a, b) => {
|
|
207
|
+
return a < b ? -1 : 1;
|
|
208
|
+
})
|
|
209
|
+
.filter((key) => {
|
|
210
|
+
return attrsConfig[key]?.description;
|
|
211
|
+
})
|
|
212
|
+
.map((key) => {
|
|
213
|
+
const {
|
|
214
|
+
defaultValue,
|
|
215
|
+
description,
|
|
216
|
+
props = {},
|
|
217
|
+
type,
|
|
218
|
+
} = attrsConfig[key] || {};
|
|
219
|
+
return (
|
|
220
|
+
<tr key={key}>
|
|
221
|
+
<td className="border px-4 py-2">{key}</td>
|
|
222
|
+
<td className="border px-4 py-2">
|
|
223
|
+
{type === "textfield" && (
|
|
224
|
+
<div>
|
|
225
|
+
<TextField
|
|
226
|
+
defaultValue={attributes[key]}
|
|
227
|
+
fullWidth
|
|
228
|
+
id={key}
|
|
229
|
+
placeholder={defaultValue}
|
|
230
|
+
variant="standard"
|
|
231
|
+
{...props}
|
|
232
|
+
/>
|
|
233
|
+
<div className="mt-2">
|
|
234
|
+
<Button
|
|
235
|
+
fullWidth
|
|
236
|
+
onClick={() => {
|
|
237
|
+
onChange(
|
|
238
|
+
key,
|
|
239
|
+
(
|
|
240
|
+
document.getElementById(
|
|
241
|
+
key,
|
|
242
|
+
) as HTMLInputElement
|
|
243
|
+
)?.value,
|
|
244
|
+
);
|
|
245
|
+
}}
|
|
246
|
+
>
|
|
247
|
+
Apply
|
|
248
|
+
</Button>
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
251
|
+
)}
|
|
252
|
+
|
|
253
|
+
{type === "checkbox" && (
|
|
254
|
+
<Checkbox
|
|
255
|
+
defaultChecked={
|
|
256
|
+
(searchParams.get(key) || defaultValue) === "true"
|
|
257
|
+
}
|
|
258
|
+
onChange={(evt) => {
|
|
259
|
+
onChange(key, evt.target.checked ? "true" : "false");
|
|
260
|
+
}}
|
|
261
|
+
/>
|
|
262
|
+
)}
|
|
263
|
+
|
|
264
|
+
{type === "select" && (
|
|
265
|
+
<Select
|
|
266
|
+
defaultValue={searchParams.get(key) || defaultValue}
|
|
267
|
+
fullWidth
|
|
268
|
+
onChange={(evt) => {
|
|
269
|
+
onChange(key, evt.target.value);
|
|
270
|
+
}}
|
|
271
|
+
variant="standard"
|
|
272
|
+
>
|
|
273
|
+
<MenuItem value="travic_v2">Travic v2</MenuItem>
|
|
274
|
+
<MenuItem value="base_dark_v2">Dark v2</MenuItem>
|
|
275
|
+
</Select>
|
|
276
|
+
)}
|
|
277
|
+
</td>
|
|
278
|
+
<td className="border p-4">
|
|
279
|
+
{description}{" "}
|
|
280
|
+
{defaultValue && (
|
|
281
|
+
<>
|
|
282
|
+
<br />
|
|
283
|
+
<i>Default to "{defaultValue}"</i>
|
|
284
|
+
</>
|
|
285
|
+
)}
|
|
286
|
+
</td>
|
|
287
|
+
</tr>
|
|
288
|
+
);
|
|
289
|
+
})}
|
|
290
|
+
</tbody>
|
|
291
|
+
</table>
|
|
292
|
+
</div>
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export default WebComponentDoc;
|
|
Binary file
|